Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IA2
GMS
Commits
bc79d18c
Commit
bc79d18c
authored
Dec 02, 2019
by
Sonia Zorba
Browse files
Implemented keep alive and audit logging; minor improvements
parent
d6ee290f
Changes
27
Hide whitespace changes
Inline
Side-by-side
gms-ui/package-lock.json
View file @
bc79d18c
This source diff could not be displayed because it is too large. You can
view the blob
instead.
gms-ui/package.json
View file @
bc79d18c
...
...
@@ -8,29 +8,29 @@
"lint"
:
"vue-cli-service lint"
},
"dependencies"
:
{
"@fortawesome/fontawesome-svg-core"
:
"^1.2.
19
"
,
"@fortawesome/free-solid-svg-icons"
:
"^5.
9.0
"
,
"@fortawesome/vue-fontawesome"
:
"^0.1.
6
"
,
"bootstrap-vue"
:
"^2.
0
.0
-rc.27
"
,
"core-js"
:
"^2.6.
5
"
,
"@fortawesome/fontawesome-svg-core"
:
"^1.2.
25
"
,
"@fortawesome/free-solid-svg-icons"
:
"^5.
11.2
"
,
"@fortawesome/vue-fontawesome"
:
"^0.1.
8
"
,
"bootstrap-vue"
:
"^2.
1
.0"
,
"core-js"
:
"^2.6.
10
"
,
"debounce"
:
"^1.2.0"
,
"vue"
:
"^2.6.10"
,
"vuex"
:
"^3.1.
1
"
"vuex"
:
"^3.1.
2
"
},
"devDependencies"
:
{
"@babel/polyfill"
:
"^7.
4.4
"
,
"@vue/cli-plugin-babel"
:
"^3.
8.0
"
,
"@vue/cli-plugin-eslint"
:
"^3.
8.0
"
,
"@vue/cli-service"
:
"^3.
8.0
"
,
"babel-eslint"
:
"^10.0.
1
"
,
"bootstrap"
:
"^4.
3
.1"
,
"@babel/polyfill"
:
"^7.
7.0
"
,
"@vue/cli-plugin-babel"
:
"^3.
12.1
"
,
"@vue/cli-plugin-eslint"
:
"^3.
12.1
"
,
"@vue/cli-service"
:
"^3.
12.1
"
,
"babel-eslint"
:
"^10.0.
3
"
,
"bootstrap"
:
"^4.
4
.1"
,
"eslint"
:
"^5.16.0"
,
"eslint-plugin-vue"
:
"^5.0.0"
,
"mutationobserver-shim"
:
"^0.3.3"
,
"node-sass"
:
"^4.1
2
.0"
,
"popper.js"
:
"^1.1
5
.0"
,
"portal-vue"
:
"^2.1.
4
"
,
"sass-loader"
:
"^7.
1.0
"
,
"node-sass"
:
"^4.1
3
.0"
,
"popper.js"
:
"^1.1
6
.0"
,
"portal-vue"
:
"^2.1.
6
"
,
"sass-loader"
:
"^7.
3.1
"
,
"vue-cli-plugin-bootstrap-vue"
:
"^0.4.0"
,
"vue-template-compiler"
:
"^2.6.10"
},
...
...
gms-ui/src/App.vue
View file @
bc79d18c
...
...
@@ -56,6 +56,8 @@ export default {
.
then
(
model
=>
{
this
.
$store
.
commit
(
'
updateHomePageModel
'
,
model
);
});
setInterval
(
client
.
keepAlive
,
60000
);
}
}
</
script
>
...
...
gms-ui/src/api/mock/index.js
View file @
bc79d18c
...
...
@@ -8,7 +8,7 @@ import permission from './data/permission';
import
search
from
'
./data/search
'
;
import
openUserSearchResult
from
'
./data/openUserSearchResult
'
;
const
fetch
=
(
mockData
,
time
=
0
)
=>
{
const
fetch
=
(
mockData
,
time
=
50
0
)
=>
{
return
new
Promise
((
resolve
)
=>
{
setTimeout
(()
=>
{
resolve
(
mockData
)
...
...
@@ -18,51 +18,54 @@ const fetch = (mockData, time = 0) => {
export
default
{
fetchHomePageModel
()
{
return
fetch
(
home
,
500
);
return
fetch
(
home
);
},
fetchGroupsTab
()
{
return
fetch
(
groups
,
500
);
return
fetch
(
groups
);
},
fetchGroupsPanel
()
{
return
fetch
(
groupsPanel
,
500
);
return
fetch
(
groupsPanel
);
},
fetchMembersPanel
()
{
return
fetch
(
membersPanel
,
500
);
return
fetch
(
membersPanel
);
},
fetchPermissionsPanel
()
{
return
fetch
(
permissionsPanel
,
500
);
return
fetch
(
permissionsPanel
);
},
addGroup
()
{
return
fetch
(
groupsPanel
,
500
);
return
fetch
(
groupsPanel
);
},
renameGroup
()
{
return
fetch
(
groupsPanel
,
500
);
return
fetch
(
groupsPanel
);
},
removeGroup
()
{
return
fetch
(
groupsPanel
,
500
);
return
fetch
(
groupsPanel
);
},
searchUser
()
{
return
fetch
(
searchUser
,
500
);
return
fetch
(
searchUser
);
},
addPermission
()
{
return
fetch
(
permissionsPanel
,
500
);
return
fetch
(
permissionsPanel
);
},
getPermission
()
{
return
fetch
(
permission
,
500
);
return
fetch
(
permission
);
},
removePermission
()
{
return
fetch
(
permissionsPanel
,
500
);
return
fetch
(
permissionsPanel
);
},
addMember
()
{
return
fetch
(
membersPanel
,
500
);
return
fetch
(
membersPanel
);
},
removeMember
()
{
return
fetch
(
membersPanel
,
500
);
return
fetch
(
membersPanel
);
},
search
()
{
return
fetch
(
search
,
500
);
return
fetch
(
search
);
},
openUserSearchResult
()
{
return
fetch
(
openUserSearchResult
,
500
);
return
fetch
(
openUserSearchResult
);
},
setKeepAlive
()
{
return
fetch
({});
}
}
gms-ui/src/api/server/index.js
View file @
bc79d18c
const
BASE_API_URL
=
process
.
env
.
VUE_APP_API_BASE_URL
;
function
apiRequest
(
url
,
options
)
{
loading
(
true
);
function
apiRequest
(
url
,
options
,
showLoading
=
true
)
{
if
(
showLoading
)
{
loading
(
true
);
}
return
new
Promise
((
resolve
)
=>
{
fetch
(
url
,
options
)
.
then
(
response
=>
{
loading
(
false
);
if
([
200
,
201
,
204
,
400
].
includes
(
response
.
status
))
{
// valid status codes
resolve
(
response
.
json
());
if
(
response
.
status
===
204
)
{
resolve
({});
}
else
{
resolve
(
response
.
json
());
}
}
else
{
response
.
json
().
then
(
jsonValue
=>
dispatchApiErrorEvent
(
jsonValue
));
}
...
...
@@ -304,5 +310,14 @@ export default {
'
Accept
'
:
'
application/json
'
,
}
});
},
keepAlive
()
{
let
url
=
BASE_API_URL
+
'
keepAlive
'
;
return
apiRequest
(
url
,
{
method
:
'
GET
'
,
cache
:
'
no-cache
'
,
credentials
:
'
include
'
},
false
);
}
};
gms-ui/src/components/modals/AddGroupModal.vue
View file @
bc79d18c
...
...
@@ -4,7 +4,7 @@
<label
class=
"w-25"
for=
"new-group-name-input"
>
Group name:
</label>
<b-form-input
v-model=
"newGroupName"
id=
"new-group-name-input"
ref=
"newGroupNameInput"
class=
"w-75"
aria-describedby=
"new-group-name-input-feedback"
:state=
"newGroupNameState"
v-on:input=
"resetError"
@
keydown.native.enter=
"addGroup"
>
</b-form-input>
<b-form-invalid-feedback
id=
"new-group-name-input-feedback"
>
{{
newGroupNameError
}}
</b-form-invalid-feedback>
<b-form-invalid-feedback
id=
"new-group-name-input-feedback"
class=
"text-right"
>
{{
newGroupNameError
}}
</b-form-invalid-feedback>
<b-form-checkbox
class=
"mt-3 ml-3"
v-model=
"leaf"
>
is leaf
</b-form-checkbox>
</b-form>
</b-modal>
...
...
@@ -18,14 +18,15 @@ export default {
computed
:
{
newGroupNameState
()
{
if
(
this
.
newGroupNameError
)
{
return
'
invalid
'
;
return
false
;
}
return
null
;
}
},
data
:
function
()
{
return
{
newGroupName
:
null
,
newGroupNameError
:
null
,
newGroupName
:
''
,
newGroupNameError
:
''
,
leaf
:
false
};
},
...
...
gms-ui/src/components/modals/RenameGroupModal.vue
View file @
bc79d18c
...
...
@@ -4,7 +4,7 @@
<label
class=
"w-25"
for=
"new-group-name-input"
>
Group name:
</label>
<b-form-input
v-model=
"newGroupName"
id=
"new-group-name-input"
class=
"w-75"
aria-describedby=
"new-group-name-input-feedback"
:state=
"newGroupNameState"
v-on:input=
"resetError"
>
</b-form-input>
<b-form-invalid-feedback
id=
"new-group-name-input-feedback"
>
{{
newGroupNameError
}}
</b-form-invalid-feedback>
<b-form-invalid-feedback
id=
"new-group-name-input-feedback"
class=
"text-right"
>
{{
newGroupNameError
}}
</b-form-invalid-feedback>
<b-form-checkbox
class=
"mt-3 ml-3"
v-model=
"leaf"
>
is leaf
</b-form-checkbox>
</b-form>
</b-modal>
...
...
@@ -18,16 +18,17 @@ export default {
computed
:
{
newGroupNameState
()
{
if
(
this
.
newGroupNameError
)
{
return
'
invalid
'
;
return
false
;
}
return
null
;
}
},
data
:
function
()
{
return
{
groupId
:
null
,
oldGroupName
:
null
,
newGroupName
:
null
,
newGroupNameError
:
null
,
groupId
:
''
,
oldGroupName
:
''
,
newGroupName
:
''
,
newGroupNameError
:
''
,
leaf
:
false
};
},
...
...
@@ -55,7 +56,6 @@ export default {
return
;
}
let
parent
=
this
.
$store
.
getters
.
selectedGroupId
;
client
.
renameGroup
(
this
.
groupId
,
this
.
newGroupName
,
this
.
leaf
,
this
.
$store
.
state
.
input
)
.
then
(
res
=>
{
if
(
res
.
status
===
400
)
{
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/CustomIdTokenConverter.java
View file @
bc79d18c
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
java.util.List
;
import
java.util.Map
;
import
org.springframework.security.core.Authentication
;
...
...
@@ -12,9 +13,11 @@ import org.springframework.security.oauth2.provider.token.store.jwk.JwkTokenStor
public
class
CustomIdTokenConverter
extends
DefaultUserAuthenticationConverter
{
private
final
JwkTokenStore
jwkTokenStore
;
private
final
LoggingDAO
loggingDAO
;
public
CustomIdTokenConverter
(
JwkTokenStore
jwkTokenStore
)
{
public
CustomIdTokenConverter
(
JwkTokenStore
jwkTokenStore
,
LoggingDAO
loggingDAO
)
{
this
.
jwkTokenStore
=
jwkTokenStore
;
this
.
loggingDAO
=
loggingDAO
;
}
@Override
...
...
@@ -29,6 +32,7 @@ public class CustomIdTokenConverter extends DefaultUserAuthenticationConverter {
Map
<
String
,
Object
>
claims
=
token
.
getAdditionalInformation
();
String
principal
=
(
String
)
claims
.
get
(
"sub"
);
loggingDAO
.
logAction
(
"Login by "
+
principal
);
List
<
GrantedAuthority
>
authorities
=
AuthorityUtils
.
createAuthorityList
(
"ROLE_USER"
);
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/JWTFilter.java
View file @
bc79d18c
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
java.io.IOException
;
import
java.security.Principal
;
import
java.util.Map
;
...
...
@@ -17,9 +18,11 @@ import org.springframework.security.oauth2.provider.token.store.jwk.JwkTokenStor
public
class
JWTFilter
implements
Filter
{
private
final
JwkTokenStore
jwkTokenStore
;
private
final
LoggingDAO
loggingDAO
;
public
JWTFilter
(
JwkTokenStore
jwkTokenStore
)
{
public
JWTFilter
(
JwkTokenStore
jwkTokenStore
,
LoggingDAO
loggingDAO
)
{
this
.
jwkTokenStore
=
jwkTokenStore
;
this
.
loggingDAO
=
loggingDAO
;
}
@Override
...
...
@@ -30,6 +33,7 @@ public class JWTFilter implements Filter {
String
authHeader
=
request
.
getHeader
(
"Authorization"
);
if
(
authHeader
==
null
)
{
loggingDAO
.
logAction
(
"Attempt to access WS without token"
);
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
"Missing Authorization token"
);
return
;
}
...
...
@@ -38,6 +42,7 @@ public class JWTFilter implements Filter {
OAuth2AccessToken
accessToken
=
jwkTokenStore
.
readAccessToken
(
authHeader
);
if
(
accessToken
.
isExpired
())
{
loggingDAO
.
logAction
(
"Attempt to access WS with expired token"
);
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
"Access token is expired"
);
return
;
}
...
...
@@ -45,11 +50,13 @@ public class JWTFilter implements Filter {
Map
<
String
,
Object
>
claims
=
accessToken
.
getAdditionalInformation
();
if
(
claims
.
get
(
"sub"
)
==
null
)
{
loggingDAO
.
logAction
(
"Attempt to access WS with invalid token"
);
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
"Invalid access token: missing sub claim"
);
return
;
}
ServletRequest
wrappedRequest
=
new
ServletRequestWithJWTPrincipal
(
request
,
claims
);
ServletRequestWithJWTPrincipal
wrappedRequest
=
new
ServletRequestWithJWTPrincipal
(
request
,
claims
);
loggingDAO
.
logAction
(
"WS access from "
+
wrappedRequest
.
getUserPrincipal
().
getName
());
fc
.
doFilter
(
wrappedRequest
,
res
);
}
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/OAuth2Config.java
View file @
bc79d18c
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
java.util.List
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.beans.factory.annotation.Value
;
...
...
@@ -32,11 +33,11 @@ public class OAuth2Config extends AuthorizationServerEndpointsConfiguration {
private
String
clientId
;
@Bean
public
ResourceServerTokenServices
resourceServerTokenServices
(
JwkTokenStore
jwkTokenStore
)
{
public
ResourceServerTokenServices
resourceServerTokenServices
(
JwkTokenStore
jwkTokenStore
,
LoggingDAO
loggingDAO
)
{
GetTokenDataService
tokenService
=
new
GetTokenDataService
();
DefaultAccessTokenConverter
accessTokenConverter
=
new
DefaultAccessTokenConverter
();
accessTokenConverter
.
setUserTokenConverter
(
new
CustomIdTokenConverter
(
jwkTokenStore
));
accessTokenConverter
.
setUserTokenConverter
(
new
CustomIdTokenConverter
(
jwkTokenStore
,
loggingDAO
));
tokenService
.
setAccessTokenConverter
(
accessTokenConverter
);
tokenService
.
setCheckTokenEndpointUrl
(
checkTokenEndpointUrl
);
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java
View file @
bc79d18c
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
java.util.Arrays
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -70,9 +71,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
* Checks the BasicAuth for GMS clients.
*/
@Bean
public
FilterRegistrationBean
serviceBasicAuthFilter
()
{
public
FilterRegistrationBean
serviceBasicAuthFilter
(
LoggingDAO
loggingDAO
)
{
FilterRegistrationBean
bean
=
new
FilterRegistrationBean
();
bean
.
setFilter
(
new
ServiceBasicAuthFilter
());
bean
.
setFilter
(
new
ServiceBasicAuthFilter
(
loggingDAO
));
bean
.
addUrlPatterns
(
"/ws/basic/*"
);
bean
.
setOrder
(
Ordered
.
HIGHEST_PRECEDENCE
);
return
bean
;
...
...
@@ -82,9 +83,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
* Checks JWT for web services.
*/
@Bean
public
FilterRegistrationBean
serviceJWTFilter
(
JwkTokenStore
jwkTokenStore
)
{
public
FilterRegistrationBean
serviceJWTFilter
(
JwkTokenStore
jwkTokenStore
,
LoggingDAO
loggingDAO
)
{
FilterRegistrationBean
bean
=
new
FilterRegistrationBean
();
bean
.
setFilter
(
new
JWTFilter
(
jwkTokenStore
));
bean
.
setFilter
(
new
JWTFilter
(
jwkTokenStore
,
loggingDAO
));
bean
.
addUrlPatterns
(
"/ws/jwt/*"
);
bean
.
setOrder
(
Ordered
.
HIGHEST_PRECEDENCE
);
return
bean
;
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/ServiceBasicAuthFilter.java
View file @
bc79d18c
...
...
@@ -2,6 +2,7 @@ package it.inaf.ia2.gms.authn;
import
it.inaf.ia2.gms.exception.UnauthorizedException
;
import
it.inaf.ia2.gms.persistence.ClientsDAO
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
it.inaf.ia2.gms.persistence.model.ClientEntity
;
import
java.io.IOException
;
import
java.nio.charset.StandardCharsets
;
...
...
@@ -22,6 +23,12 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
public
class
ServiceBasicAuthFilter
implements
Filter
{
private
final
LoggingDAO
loggingDAO
;
public
ServiceBasicAuthFilter
(
LoggingDAO
loggingDAO
)
{
this
.
loggingDAO
=
loggingDAO
;
}
@Override
public
void
doFilter
(
ServletRequest
req
,
ServletResponse
res
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
...
...
@@ -31,11 +38,14 @@ public class ServiceBasicAuthFilter implements Filter {
try
{
validateBasicAuth
(
request
);
}
catch
(
UnauthorizedException
ex
)
{
loggingDAO
.
logAction
(
"Unauthorized BasicAuth WS request"
);
((
HttpServletResponse
)
res
).
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
ex
.
getMessage
());
return
;
}
}
loggingDAO
.
logAction
(
"BasicAuth WS request"
);
chain
.
doFilter
(
req
,
res
);
}
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/SessionData.java
View file @
bc79d18c
...
...
@@ -18,6 +18,7 @@ public class SessionData {
private
String
userName
;
private
String
accessToken
;
private
String
refreshToken
;
private
long
expiration
;
@PostConstruct
public
void
init
()
{
...
...
@@ -26,6 +27,7 @@ public class SessionData {
userName
=
(
String
)
authn
.
getAttributes
().
get
(
"name"
);
accessToken
=
(
String
)
authn
.
getAccessToken
().
getValue
();
refreshToken
=
authn
.
getRefreshToken
();
setExpiresIn
(
authn
.
getAccessToken
().
getExpiresIn
());
}
public
String
getUserId
()
{
...
...
@@ -51,4 +53,12 @@ public class SessionData {
public
String
getUserName
()
{
return
userName
;
}
public
void
setExpiresIn
(
int
expiresIn
)
{
this
.
expiration
=
System
.
currentTimeMillis
()
+
expiresIn
*
1000
;
}
public
long
getExpiresIn
()
{
return
(
System
.
currentTimeMillis
()
-
expiration
)
/
1000
;
}
}
gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java
View file @
bc79d18c
...
...
@@ -11,6 +11,7 @@ import it.inaf.ia2.gms.model.request.DeleteGroupRequest;
import
it.inaf.ia2.gms.model.request.GroupsRequest
;
import
it.inaf.ia2.gms.model.request.RenameGroupRequest
;
import
it.inaf.ia2.gms.model.request.SearchFilterRequest
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
it.inaf.ia2.gms.persistence.model.GroupEntity
;
import
it.inaf.ia2.gms.service.GroupsService
;
import
it.inaf.ia2.gms.service.GroupsTreeBuilder
;
...
...
@@ -46,6 +47,9 @@ public class GroupsController {
@Autowired
private
GroupsTabResponseBuilder
groupsTabResponseBuilder
;
@Autowired
private
LoggingDAO
loggingDAO
;
@GetMapping
(
value
=
"/groups"
,
produces
=
MediaType
.
APPLICATION_JSON_UTF8_VALUE
)
public
ResponseEntity
<?>
getGroupsTab
(
@Valid
GroupsRequest
request
)
{
if
(
request
.
isOnlyPanel
())
{
...
...
@@ -64,10 +68,12 @@ public class GroupsController {
GroupEntity
parent
=
groupsService
.
getGroupById
(
request
.
getParentGroupId
());
if
(
permissionsService
.
getUserPermissionForGroup
(
parent
,
session
.
getUserId
())
!=
Permission
.
ADMIN
)
{
loggingDAO
.
logAction
(
"Unauthorized create group request, group_name="
+
request
.
getNewGroupName
());
throw
new
UnauthorizedException
(
"Missing admin permission"
);
}
groupsService
.
addGroup
(
parent
,
request
.
getNewGroupName
(),
request
.
isLeaf
());
loggingDAO
.
logAction
(
"Added group: parent_path="
+
parent
.
getPath
()
+
", group_name="
+
request
.
getNewGroupName
());
PaginatedData
<
GroupNode
>
groupsPanel
=
getGroupsPanel
(
parent
,
request
);
...
...
@@ -80,10 +86,12 @@ public class GroupsController {
GroupEntity
group
=
groupsService
.
getGroupById
(
groupId
);
if
(
permissionsService
.
getUserPermissionForGroup
(
group
,
session
.
getUserId
())
!=
Permission
.
ADMIN
)
{
loggingDAO
.
logAction
(
"Unauthorized rename group request, group_id="
+
groupId
);
throw
new
UnauthorizedException
(
"Missing admin permission"
);
}
GroupEntity
renamedGroup
=
groupsService
.
renameGroup
(
group
,
request
.
getNewGroupName
(),
request
.
isLeaf
());
loggingDAO
.
logAction
(
"Group renamed, group_id="
+
groupId
+
", new name: "
+
request
.
getNewGroupName
());
GroupEntity
parent
=
groupsService
.
getGroupByPath
(
renamedGroup
.
getParentPath
());
...
...
@@ -98,11 +106,12 @@ public class GroupsController {
GroupEntity
group
=
groupsService
.
getGroupById
(
groupId
);
if
(
permissionsService
.
getUserPermissionForGroup
(
group
,
session
.
getUserId
())
!=
Permission
.
ADMIN
)
{
loggingDAO
.
logAction
(
"Unauthorized delete group request, group_id="
+
groupId
);
throw
new
UnauthorizedException
(
"Missing admin permission"
);
}
GroupEntity
parent
=
groupsService
.
deleteGroup
(
group
);
loggingDAO
.
logAction
(
"Group deleted, group_id="
+
groupId
);
PaginatedData
<
GroupNode
>
groupsPanel
=
getGroupsPanel
(
parent
,
request
);
return
ResponseEntity
.
ok
(
groupsPanel
);
...
...
gms/src/main/java/it/inaf/ia2/gms/controller/KeepAliveController.java
0 → 100644
View file @
bc79d18c
package
it.inaf.ia2.gms.controller
;
import
it.inaf.ia2.gms.authn.SessionData
;
import
it.inaf.ia2.gms.rap.RapClient
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
public
class
KeepAliveController
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
KeepAliveController
.
class
);
@Autowired
private
SessionData
sessionData
;
@Autowired
private
RapClient
rapClient
;
@GetMapping
(
"/keepAlive"
)
public
ResponseEntity
<?>
keepAlive
()
{
LOG
.
trace
(
"Keepalive called"
);
if
(
sessionData
.
getExpiresIn
()
<
60
)
{
rapClient
.
refreshToken
();
LOG
.
trace
(
"RAP token refreshed"
);
}
return
ResponseEntity
.
noContent
().
build
();
}
}
gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java
View file @
bc79d18c
...
...
@@ -9,6 +9,7 @@ import it.inaf.ia2.gms.model.Permission;
import
it.inaf.ia2.gms.model.RapUser
;
import
it.inaf.ia2.gms.model.request.RemoveMemberRequest
;
import
it.inaf.ia2.gms.model.request.TabRequest
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
it.inaf.ia2.gms.persistence.model.GroupEntity
;
import
it.inaf.ia2.gms.service.GroupsService
;
import
it.inaf.ia2.gms.service.MembersService
;
...
...
@@ -40,6 +41,9 @@ public class MembersController {
@Autowired
private
MembersService
membersService
;
@Autowired
private
LoggingDAO
loggingDAO
;
@GetMapping
(
value
=
"/members"
,
produces
=
MediaType
.
APPLICATION_JSON_UTF8_VALUE
)
public
ResponseEntity
<
PaginatedData
<
RapUser
>>
getMembersTab
(
TabRequest
request
)
{
...
...
@@ -66,9 +70,13 @@ public class MembersController {
if
(
currentUserPermission
==
Permission
.
MANAGE_MEMBERS
)
{
// Automatically assign the VIEW_MEMBERS permission ("Add collaborator" feature)
permissionsService
.
addPermission
(
group
,
request
.
getUserId
(),
Permission
.
VIEW_MEMBERS
);
loggingDAO
.
logAction
(
"Added permission, group_id="
+
group
.
getId
()
+
", user_id="
+
request
.
getUserId
()
+
", permission="
+
Permission
.
VIEW_MEMBERS
);
}
else
if
(
request
.
getPermission
()
!=
null
)
{
// Admin users can specify a permission
permissionsService
.
addPermission
(
group
,
request
.
getUserId
(),
request
.
getPermission
());
loggingDAO
.
logAction
(
"Added permission, group_id="
+
group
.
getId
()
+
", user_id="
+
request
.
getUserId
()
+
", permission="
+
request
.
getPermission
());
}
return
new
ResponseEntity
<>(
getMembersPanel
(
request
),
HttpStatus
.
CREATED
);
...
...
@@ -81,6 +89,7 @@ public class MembersController {
Permission
currentUserPermission
=
verifyCurrentUserCanManageMembers
(
group
);
membersService
.
removeMember
(
group
.
getId
(),
request
.
getUserId
());
loggingDAO
.
logAction
(
"Member removed, group_id="
+
group
.
getId
()
+
", user_id="
+
request
.
getUserId
());
// For users having the MANAGE_MEMBERS permission, the VIEW_MEMBERS permission
// is automatically assigned when they add a member ("Add collaborator" feature).
...
...
@@ -95,6 +104,7 @@ public class MembersController {
if
(
removeCollaborator
||
adminRemovePermission
)
{
permissionsService
.
removePermission
(
group
,
request
.
getUserId
());
loggingDAO
.
logAction
(
"Permission removed, group_id="
+
group
.
getId
()
+
", user_id="
+
request
.
getUserId
());
}
return
ResponseEntity
.
ok
(
getMembersPanel
(
request
));
...
...
gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java
View file @
bc79d18c
...
...
@@ -9,6 +9,7 @@ import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
import
it.inaf.ia2.gms.model.Permission
;
import
it.inaf.ia2.gms.model.UserPermission
;
import
it.inaf.ia2.gms.model.request.TabRequest
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
it.inaf.ia2.gms.persistence.model.GroupEntity
;
import
it.inaf.ia2.gms.service.GroupsService
;
import
it.inaf.ia2.gms.service.PermissionsService
;
...
...
@@ -39,6 +40,9 @@ public class PermissionsController {
@Autowired
private
PermissionsService
permissionsService
;
@Autowired
private
LoggingDAO
loggingDAO
;
@GetMapping
(
value
=
"/permissions"
,
produces
=
MediaType
.
APPLICATION_JSON_UTF8_VALUE
)
public
ResponseEntity
<
PaginatedData
<
UserPermission
>>
getPermissionsTab
(
TabRequest
request
)
{