Skip to content
GitLab
Explore
Sign in
IA2
GMS
Compare revisions
e60cd7fbff9fc1e327082685d51dfb507aa2172e to 6eef3264c5891520828c756661ce3da8d739a67f
Hide whitespace changes
Inline
Side-by-side
gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemoveMemberTest.java
0 → 100644
View file @
6eef3264
package
it.inaf.ia2.gms.client.call
;
import
it.inaf.ia2.gms.client.BaseGmsClientTest
;
import
java.util.concurrent.CompletableFuture
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
org.mockito.junit.jupiter.MockitoExtension
;
@ExtendWith
(
MockitoExtension
.
class
)
public
class
RemoveMemberTest
extends
BaseGmsClientTest
{
@BeforeEach
@Override
public
void
init
()
{
super
.
init
();
}
@Test
public
void
testRemoveMember
()
{
CompletableFuture
response
=
CompletableFuture
.
completedFuture
(
getMockedResponse
(
204
));
when
(
httpClient
.
sendAsync
(
any
(),
any
())).
thenReturn
(
response
);
gmsClient
.
removeMember
(
"LBT.INAF"
,
"user"
);
verify
(
httpClient
,
times
(
1
)).
sendAsync
(
endpointEq
(
"DELETE"
,
"ws/jwt/membership/LBT.INAF?user_id=user"
),
any
());
}
}
gms-client/gms-client/src/test/java/it/inaf/ia2/gms/client/call/RemovePermissionTest.java
0 → 100644
View file @
6eef3264
package
it.inaf.ia2.gms.client.call
;
import
it.inaf.ia2.gms.client.BaseGmsClientTest
;
import
java.util.concurrent.CompletableFuture
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
org.mockito.junit.jupiter.MockitoExtension
;
@ExtendWith
(
MockitoExtension
.
class
)
public
class
RemovePermissionTest
extends
BaseGmsClientTest
{
@BeforeEach
@Override
public
void
init
()
{
super
.
init
();
}
@Test
public
void
testRemovePermission
()
{
CompletableFuture
response
=
CompletableFuture
.
completedFuture
(
getMockedResponse
(
204
));
when
(
httpClient
.
sendAsync
(
any
(),
any
())).
thenReturn
(
response
);
gmsClient
.
removePermission
(
"LBT.INAF"
,
"user"
);
verify
(
httpClient
,
times
(
1
)).
sendAsync
(
endpointEq
(
"DELETE"
,
"ws/jwt/permission/LBT.INAF?user_id=user"
),
any
());
}
}
gms-ui/src/components/GroupsBreadcrumb.vue
View file @
6eef3264
...
...
@@ -6,7 +6,7 @@
<span
v-if=
"group.active"
>
{{
group
.
groupName
}}
</span>
</li>
</ol>
<a
v-if=
"currentGroup"
:href=
"'group/status
/
' + currentGroup.groupId"
:download=
"currentGroup.groupName + '.csv'"
id=
"csv-status-download"
title=
"Download CSV"
>
<a
v-if=
"currentGroup"
:href=
"'group/status
?groupId=
' + currentGroup.groupId"
:download=
"currentGroup.groupName + '.csv'"
id=
"csv-status-download"
title=
"Download CSV"
>
<font-awesome-icon
icon=
"download"
></font-awesome-icon>
</a>
</nav>
...
...
gms/pom.xml
View file @
6eef3264
...
...
@@ -40,7 +40,7 @@
</dependency>
<dependency>
<groupId>
${project.groupId}
</groupId>
<artifactId>
A
uth
L
ib
</artifactId>
<artifactId>
a
uth
-l
ib
</artifactId>
<version>
2.0.0-SNAPSHOT
</version>
</dependency>
<dependency>
...
...
@@ -68,36 +68,46 @@
</dependency>
</dependencies>
<profiles>
<profile>
<id>
build-gui
</id>
<build>
<plugins>
<plugin>
<groupId>
com.github.eirslett
</groupId>
<artifactId>
frontend-maven-plugin
</artifactId>
<version>
1.7.6
</version>
<configuration>
<nodeVersion>
v12.6.0
</nodeVersion>
<environmentVariables>
<VUE_APP_SHOW_USER_ID_IN_SEARCH>
${show.user_id_in_search}
</VUE_APP_SHOW_USER_ID_IN_SEARCH>
</environmentVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>
install-node-and-npm
</goal>
</goals>
</execution>
<execution>
<id>
npm install
</id>
<goals>
<goal>
npm
</goal>
</goals>
<configuration>
<arguments>
run build --prefix ../gms-ui
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<finalName>
gms
</finalName>
<plugins>
<plugin>
<groupId>
com.github.eirslett
</groupId>
<artifactId>
frontend-maven-plugin
</artifactId>
<version>
1.7.6
</version>
<configuration>
<nodeVersion>
v12.6.0
</nodeVersion>
<environmentVariables>
<VUE_APP_SHOW_USER_ID_IN_SEARCH>
${show.user_id_in_search}
</VUE_APP_SHOW_USER_ID_IN_SEARCH>
</environmentVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>
install-node-and-npm
</goal>
</goals>
</execution>
<execution>
<id>
npm install
</id>
<goals>
<goal>
npm
</goal>
</goals>
<configuration>
<arguments>
run build --prefix ../gms-ui
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>
maven-resources-plugin
</artifactId>
<version>
3.1.0
</version>
...
...
@@ -184,4 +194,10 @@
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>
ia2.snapshot
</id>
<url>
http://repo.ia2.inaf.it/maven/repository/snapshots
</url>
</repository>
</repositories>
</project>
gms/src/main/java/it/inaf/ia2/gms/GmsApplication.java
View file @
6eef3264
...
...
@@ -2,14 +2,11 @@ package it.inaf.ia2.gms;
import
it.inaf.ia2.aa.AuthConfig
;
import
it.inaf.ia2.aa.ServiceLocator
;
import
it.inaf.ia2.aa.UriCustomizer
;
import
it.inaf.ia2.aa.jwt.QueryStringBuilder
;
import
static
it
.
inaf
.
ia2
.
gms
.
authn
.
ClientDbFilter
.
CLIENT_DB
;
import
it.inaf.ia2.gms.exception.BadRequestException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpSession
;
import
it.inaf.ia2.aa.UserManager
;
import
it.inaf.ia2.gms.authn.ServletRapClient
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
...
...
@@ -20,47 +17,20 @@ public class GmsApplication {
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
GmsApplication
.
class
,
args
);
}
AuthConfig
authConfig
=
ServiceLocator
.
getInstance
().
getConfig
();
final
String
defaultAuthorizationUri
=
authConfig
.
getUserAuthorizationUri
();
authConfig
.
setAuthorizationUriCustomizer
(
new
UriCustomizer
()
{
@Override
public
String
getBaseUri
(
HttpServletRequest
req
)
{
// for a better security we should check for allowed redirects
String
redirect
=
req
.
getParameter
(
"redirect"
);
if
(
redirect
!=
null
)
{
return
redirect
;
}
return
defaultAuthorizationUri
;
}
@Override
public
void
customizeQueryString
(
HttpServletRequest
req
,
QueryStringBuilder
queryStringBuilder
)
{
String
clientDb
=
req
.
getParameter
(
CLIENT_DB
);
if
(
clientDb
==
null
)
{
HttpSession
session
=
req
.
getSession
(
false
);
if
(
session
!=
null
)
{
clientDb
=
(
String
)
session
.
getAttribute
(
CLIENT_DB
);
}
}
if
(
clientDb
==
null
)
{
throw
new
BadRequestException
(
"client_db not set"
);
}
queryStringBuilder
.
param
(
CLIENT_DB
,
clientDb
);
}
});
@Bean
public
AuthConfig
authConfig
()
{
return
ServiceLocator
.
getInstance
().
getConfig
();
}
final
String
defaultAccessTokenUri
=
authConfig
.
getAccessTokenUri
();
@Bean
public
UserManager
userManager
()
{
return
ServiceLocator
.
getInstance
().
getUserManager
();
}
authConfig
.
setAccessTokenUriCustomizer
(
req
->
{
String
redirect
=
req
.
getParameter
(
"token_uri"
);
if
(
redirect
!=
null
)
{
return
redirect
;
}
return
defaultAccessTokenUri
;
});
@Bean
public
ServletRapClient
servletRapClient
()
{
return
(
ServletRapClient
)
ServiceLocator
.
getInstance
().
getRapClient
();
}
}
gms/src/main/java/it/inaf/ia2/gms/authn/ClientDbFilter.java
View file @
6eef3264
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.aa.
ServiceLocator
;
import
it.inaf.ia2.aa.
jwt.JwksClient
;
import
it.inaf.ia2.aa.
AuthConfig
;
import
it.inaf.ia2.aa.
UserManager
;
import
java.io.IOException
;
import
java.net.URI
;
import
javax.servlet.Filter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.FilterConfig
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
public
class
ClientDbFilter
implements
Filter
{
public
static
final
String
CLIENT_DB
=
"client_db"
;
private
String
defaultJwksUri
;
private
JwksClient
jwksClient
;
private
final
UserManager
userManager
;
private
final
String
defaultJwksUri
;
@Override
public
void
init
(
FilterConfig
filterConfig
)
throws
ServletException
{
defaultJwksUri
=
ServiceLocator
.
getInstance
().
getConfig
().
getJwksUri
();
jwksClient
=
ServiceLocator
.
getInstance
().
getJwksClient
();
public
ClientDbFilter
(
AuthConfig
authConfig
,
UserManager
userManager
)
{
this
.
userManager
=
userManager
;
defaultJwksUri
=
URI
.
create
(
authConfig
.
getRapBaseUri
()).
resolve
(
authConfig
.
getJwksEndpoint
()).
toString
();
}
@Override
public
void
doFilter
(
ServletRequest
req
,
ServletResponse
res
,
FilterChain
fc
)
throws
IOException
,
ServletException
{
HttpServletRequest
request
=
(
HttpServletRequest
)
req
;
HttpServletResponse
response
=
(
HttpServletResponse
)
res
;
String
clientDb
=
request
.
getParameter
(
CLIENT_DB
);
if
(
clientDb
!=
null
)
{
request
.
getSession
().
setAttribute
(
CLIENT_DB
,
clientDb
);
String
newUrl
=
defaultJwksUri
.
replaceAll
(
"\\?client_name=(.*)"
,
"?client_name="
+
clientDb
);
jwksClient
.
addJwksUrl
(
newUrl
);
userManager
.
addJwksUri
(
URI
.
create
(
newUrl
)
)
;
}
fc
.
doFilter
(
req
,
res
);
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/ClientDbRapClient.java
0 → 100644
View file @
6eef3264
package
it.inaf.ia2.gms.authn
;
import
static
it
.
inaf
.
ia2
.
gms
.
authn
.
ClientDbFilter
.
CLIENT_DB
;
import
it.inaf.ia2.gms.exception.BadRequestException
;
import
it.inaf.ia2.rap.client.call.GetUserCall
;
import
it.inaf.ia2.rap.data.RapUser
;
import
java.net.URI
;
import
java.net.http.HttpRequest
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpSession
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
ClientDbRapClient
extends
ServletRapClient
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ClientDbRapClient
.
class
);
public
ClientDbRapClient
(
String
baseUrl
)
{
super
(
baseUrl
);
}
@Override
protected
HttpRequest
.
Builder
newAuthRequest
(
HttpRequest
.
Builder
requestBuilder
,
HttpServletRequest
request
)
{
return
setClientDb
(
super
.
newClientSecretRequest
(
requestBuilder
),
request
);
}
@Override
public
HttpRequest
.
Builder
newRequest
(
String
endpoint
,
HttpServletRequest
context
)
{
return
setClientDb
(
super
.
newRequest
(
endpoint
),
context
);
}
@Override
public
HttpRequest
.
Builder
newRequest
(
URI
uri
,
HttpServletRequest
context
)
{
return
setClientDb
(
super
.
newRequest
(
uri
),
context
);
}
private
HttpRequest
.
Builder
setClientDb
(
HttpRequest
.
Builder
builder
,
HttpServletRequest
request
)
{
HttpSession
session
=
request
.
getSession
(
false
);
if
(
session
!=
null
)
{
String
clientDb
=
(
String
)
session
.
getAttribute
(
"client_db"
);
if
(
clientDb
!=
null
)
{
builder
.
setHeader
(
"client_db"
,
clientDb
);
LOG
.
debug
(
"client_db="
+
clientDb
);
}
}
return
builder
;
}
@Override
public
URI
getAuthorizationUri
(
HttpServletRequest
request
)
{
// for a better security we should check for allowed redirects
String
redirect
=
request
.
getParameter
(
"redirect"
);
URI
uri
;
if
(
redirect
!=
null
)
{
uri
=
URI
.
create
(
redirect
);
}
else
{
uri
=
super
.
getAuthorizationUri
(
request
);
}
String
clientDb
=
request
.
getParameter
(
CLIENT_DB
);
if
(
clientDb
==
null
)
{
HttpSession
session
=
request
.
getSession
(
false
);
if
(
session
!=
null
)
{
clientDb
=
(
String
)
session
.
getAttribute
(
CLIENT_DB
);
}
}
if
(
clientDb
==
null
)
{
throw
new
BadRequestException
(
"client_db not set"
);
}
redirect
=
uri
.
toString
();
redirect
+=
redirect
.
contains
(
"?"
)
?
"&"
:
"?"
;
redirect
+=
CLIENT_DB
+
"="
+
clientDb
;
return
URI
.
create
(
redirect
);
}
@Override
public
URI
getAccessTokenUri
(
HttpServletRequest
request
)
{
String
tokenUri
=
request
.
getParameter
(
"token_uri"
);
if
(
tokenUri
!=
null
)
{
return
URI
.
create
(
tokenUri
);
}
return
super
.
getAccessTokenUri
(
request
);
}
@Override
public
List
<
RapUser
>
getUsers
(
String
searchText
,
HttpServletRequest
request
)
{
List
<
RapUser
>
users
=
new
GetUserCall
(
this
).
getUsers
(
searchText
,
request
);
return
users
.
stream
()
.
filter
(
u
->
u
.
getDisplayName
().
contains
(
searchText
)
||
u
.
getPrimaryEmailAddress
().
contains
(
searchText
))
.
collect
(
Collectors
.
toList
());
}
}
gms/src/main/java/it/inaf/ia2/gms/authn/GmsLoginFilter.java
View file @
6eef3264
...
...
@@ -26,6 +26,11 @@ public class GmsLoginFilter extends LoginFilter {
private
boolean
shouldNotFilter
(
HttpServletRequest
request
)
throws
ServletException
{
if
(
request
.
getUserPrincipal
()
!=
null
)
{
// Principal set using JWT
return
true
;
}
// Allow CORS check
if
(
"OPTIONS"
.
equals
(
request
.
getMethod
()))
{
return
true
;
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/JWTFilter.java
View file @
6eef3264
package
it.inaf.ia2.gms.authn
;
import
io.jsonwebtoken.Jwt
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.SigningKeyResolver
;
import
it.inaf.ia2.aa.ServiceLocator
;
import
it.inaf.ia2.aa.UserManager
;
import
it.inaf.ia2.aa.data.User
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
java.io.IOException
;
import
java.security.Principal
;
...
...
@@ -16,15 +14,16 @@ import javax.servlet.ServletResponse;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequestWrapper
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpSession
;
public
class
JWTFilter
implements
Filter
{
private
final
LoggingDAO
loggingDAO
;
private
final
SigningKeyResolver
signingKeyResolv
er
;
private
final
UserManager
userManag
er
;
public
JWTFilter
(
LoggingDAO
loggingDAO
)
{
public
JWTFilter
(
LoggingDAO
loggingDAO
,
UserManager
userManager
)
{
this
.
loggingDAO
=
loggingDAO
;
this
.
signingKeyResolver
=
ServiceLocator
.
getInstance
().
getTokenManager
().
getSigningKeyResolver
()
;
this
.
userManager
=
userManager
;
}
@Override
...
...
@@ -34,19 +33,26 @@ public class JWTFilter implements Filter {
HttpServletResponse
response
=
(
HttpServletResponse
)
res
;
String
authHeader
=
request
.
getHeader
(
"Authorization"
);
if
(
authHeader
==
null
)
{
loggingDAO
.
logAction
(
"Attempt to access WS without token"
,
request
);
response
.
sendError
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
"Missing Authorization token"
);
if
(
request
.
isRequestedSessionIdValid
())
{
HttpSession
session
=
request
.
getSession
(
false
);
User
user
=
(
User
)
session
.
getAttribute
(
"user_data"
);
if
(
user
!=
null
)
{
ServletRequestWithSessionPrincipal
wrappedRequest
=
new
ServletRequestWithSessionPrincipal
(
request
,
user
);
fc
.
doFilter
(
wrappedRequest
,
res
);
return
;
}
}
fc
.
doFilter
(
req
,
res
);
return
;
}
authHeader
=
authHeader
.
replace
(
"Bearer"
,
""
).
trim
();
String
token
=
authHeader
.
replace
(
"Bearer"
,
""
).
trim
();
Jwt
jwt
=
Jwts
.
parser
()
.
setSigningKeyResolver
(
signingKeyResolver
)
.
parse
(
authHeader
);
Map
<
String
,
Object
>
claims
=
(
Map
<
String
,
Object
>)
jwt
.
getBody
();
Map
<
String
,
Object
>
claims
=
userManager
.
parseIdTokenClaims
(
token
);
if
(
claims
.
get
(
"sub"
)
==
null
)
{
loggingDAO
.
logAction
(
"Attempt to access WS with invalid token"
,
request
);
...
...
@@ -54,19 +60,34 @@ public class JWTFilter implements Filter {
return
;
}
ServletRequestWithJWTPrincipal
wrappedRequest
=
new
ServletRequestWithJWTPrincipal
(
request
,
claims
);
ServletRequestWithJWTPrincipal
wrappedRequest
=
new
ServletRequestWithJWTPrincipal
(
request
,
token
,
claims
);
loggingDAO
.
logAction
(
"WS access from "
+
wrappedRequest
.
getUserPrincipal
().
getName
(),
request
);
fc
.
doFilter
(
wrappedRequest
,
res
);
}
private
static
class
ServletRequestWithSessionPrincipal
extends
HttpServletRequestWrapper
{
private
final
User
principal
;
public
ServletRequestWithSessionPrincipal
(
HttpServletRequest
request
,
User
user
)
{
super
(
request
);
this
.
principal
=
user
;
}
@Override
public
Principal
getUserPrincipal
()
{
return
principal
;
}
}
private
static
class
ServletRequestWithJWTPrincipal
extends
HttpServletRequestWrapper
{
private
final
Principal
principal
;
private
final
Rap
Principal
principal
;
public
ServletRequestWithJWTPrincipal
(
HttpServletRequest
request
,
Map
<
String
,
Object
>
jwtClaims
)
{
public
ServletRequestWithJWTPrincipal
(
HttpServletRequest
request
,
String
token
,
Map
<
String
,
Object
>
jwtClaims
)
{
super
(
request
);
this
.
principal
=
new
RapPrincipal
(
jwtClaims
);
this
.
principal
=
new
RapPrincipal
(
token
,
jwtClaims
);
}
@Override
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/RapClient.java
0 → 100644
View file @
6eef3264
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.rap.client.BoundedRapClient
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.annotation.RequestScope
;
@Component
@RequestScope
public
class
RapClient
extends
BoundedRapClient
<
HttpServletRequest
>
{
@Autowired
public
RapClient
(
ServletRapClient
servletRapClient
,
HttpServletRequest
request
)
{
super
(
servletRapClient
,
request
);
}
}
gms/src/main/java/it/inaf/ia2/gms/authn/RapPrincipal.java
View file @
6eef3264
...
...
@@ -5,10 +5,12 @@ import java.util.Map;
public
class
RapPrincipal
implements
Principal
{
private
final
String
token
;
private
final
String
sub
;
private
final
String
altSub
;
public
RapPrincipal
(
Map
<
String
,
Object
>
jwtClaims
)
{
public
RapPrincipal
(
String
token
,
Map
<
String
,
Object
>
jwtClaims
)
{
this
.
token
=
token
;
sub
=
(
String
)
jwtClaims
.
get
(
"sub"
);
altSub
=
(
String
)
jwtClaims
.
get
(
"alt_sub"
);
}
...
...
@@ -24,4 +26,8 @@ public class RapPrincipal implements Principal {
public
String
getAlternativeName
()
{
return
altSub
;
}
public
String
getToken
()
{
return
token
;
}
}
gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java
View file @
6eef3264
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.aa.AuthConfig
;
import
it.inaf.ia2.aa.UserManager
;
import
it.inaf.ia2.gms.persistence.LoggingDAO
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -44,9 +46,9 @@ public class SecurityConfig {
}
@Bean
public
FilterRegistrationBean
clientDbFilter
()
{
public
FilterRegistrationBean
clientDbFilter
(
AuthConfig
authConfig
,
UserManager
userManager
)
{
FilterRegistrationBean
bean
=
new
FilterRegistrationBean
();
bean
.
setFilter
(
new
ClientDbFilter
());
bean
.
setFilter
(
new
ClientDbFilter
(
authConfig
,
userManager
));
bean
.
addUrlPatterns
(
"/*"
);
bean
.
setOrder
(
Ordered
.
HIGHEST_PRECEDENCE
);
return
bean
;
...
...
@@ -56,10 +58,10 @@ public class SecurityConfig {
* Checks JWT for web services.
*/
@Bean
public
FilterRegistrationBean
serviceJWTFilter
(
LoggingDAO
loggingDAO
)
{
public
FilterRegistrationBean
serviceJWTFilter
(
LoggingDAO
loggingDAO
,
UserManager
userManager
)
{
FilterRegistrationBean
bean
=
new
FilterRegistrationBean
();
bean
.
setFilter
(
new
JWTFilter
(
loggingDAO
));
bean
.
addUrlPatterns
(
"/
ws/jwt/
*"
);
bean
.
setFilter
(
new
JWTFilter
(
loggingDAO
,
userManager
));
bean
.
addUrlPatterns
(
"/*"
);
bean
.
setOrder
(
Ordered
.
HIGHEST_PRECEDENCE
);
return
bean
;
}
...
...
gms/src/main/java/it/inaf/ia2/gms/authn/ServletRapClient.java
0 → 100644
View file @
6eef3264
package
it.inaf.ia2.gms.authn
;
import
it.inaf.ia2.aa.data.User
;
import
it.inaf.ia2.rap.client.RapClient
;
import
java.security.Principal
;
import
javax.servlet.http.HttpServletRequest
;
public
class
ServletRapClient
extends
RapClient
<
HttpServletRequest
>
{
public
ServletRapClient
(
String
baseUrl
)
{
super
(
baseUrl
);
}
@Override
protected
String
getAccessToken
(
HttpServletRequest
request
)
{
Principal
principal
=
request
.
getUserPrincipal
();
if
(
principal
!=
null
)
{
if
(
principal
instanceof
User
)
{
return
((
User
)
principal
).
getAccessToken
();
}
if
(
principal
instanceof
RapPrincipal
)
{
return
((
RapPrincipal
)
principal
).
getToken
();
}
}
return
null
;
}
}
gms/src/main/java/it/inaf/ia2/gms/authn/SessionData.java
View file @
6eef3264
...
...
@@ -14,58 +14,40 @@ public class SessionData {
private
static
final
String
USER_DATA
=
"user_data"
;
private
User
user
;
@Autowired
private
HttpServletRequest
request
;
private
String
userId
;
private
String
userName
;
private
String
accessToken
;
private
String
refreshToken
;
private
long
expiration
;
@PostConstruct
public
void
init
()
{
HttpSession
session
=
request
.
getSession
(
false
);
if
(
session
!=
null
&&
session
.
getAttribute
(
USER_DATA
)
!=
null
)
{
User
user
=
(
User
)
session
.
getAttribute
(
USER_DATA
);
userId
=
user
.
getName
();
userName
=
user
.
getUserLabel
();
accessToken
=
user
.
getAccessToken
();
refreshToken
=
user
.
getRefreshToken
();
setExpiresIn
(
user
.
getExpiresIn
());
setUser
((
User
)
session
.
getAttribute
(
USER_DATA
));
}
}
public
String
getUserId
()
{
return
userId
;
}
public
String
getAccessToken
()
{
return
accessToken
;
public
void
setUser
(
User
user
)
{
this
.
user
=
user
;
}
public
void
setAccessToken
(
String
accessToken
)
{
this
.
accessToken
=
accessToken
;
}
public
String
getRefreshToken
()
{
return
refreshToken
;
public
String
getUserId
()
{
return
user
.
getName
();
}
public
void
setRefreshToken
(
String
refreshToken
)
{
this
.
refreshToken
=
refreshToken
;
public
String
getUserName
(
)
{
return
user
.
getUserLabel
()
;
}
public
String
get
UserName
()
{
return
user
Name
;
public
String
get
AccessToken
()
{
return
user
.
getAccessToken
()
;
}
public
void
setExpiresIn
(
long
expiresIn
)
{
this
.
expiration
=
System
.
currentTimeMillis
()
+
expiresIn
*
1000
;
public
String
getRefreshToken
(
)
{
return
user
.
getRefreshToken
()
;
}
public
long
getExpiresIn
()
{
return
(
expiration
-
System
.
currentTimeMillis
())
/
1000
;
return
user
.
getExpiresIn
()
;
}
}
gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java
View file @
6eef3264
package
it.inaf.ia2.gms.controller
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.opencsv.CSVWriter
;
import
it.inaf.ia2.gms.authn.SessionData
;
import
it.inaf.ia2.gms.manager.GroupStatusManager
;
import
it.inaf.ia2.gms.manager.GroupsManager
;
import
it.inaf.ia2.gms.model.request.AddGroupRequest
;
...
...
@@ -13,9 +13,13 @@ 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.model.GroupEntity
;
import
it.inaf.ia2.gms.service.GroupNameService
;
import
it.inaf.ia2.gms.service.GroupsTreeBuilder
;
import
java.io.OutputStream
;
import
java.io.OutputStreamWriter
;
import
java.util.List
;
import
java.util.Optional
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.Valid
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -28,13 +32,16 @@ import org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.PutMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
public
class
GroupsController
{
private
static
final
ObjectMapper
MAPPER
=
new
ObjectMapper
();
@Autowired
private
SessionData
session
;
private
HttpServletRequest
servletRequest
;
@Autowired
private
GroupsManager
groupsManager
;
...
...
@@ -48,6 +55,9 @@ public class GroupsController {
@Autowired
private
GroupStatusManager
groupStatusManager
;
@Autowired
private
GroupNameService
groupNameService
;
@GetMapping
(
value
=
"/groups"
,
produces
=
MediaType
.
APPLICATION_JSON_VALUE
)
public
ResponseEntity
<?>
getGroupsTab
(
@Valid
GroupsRequest
request
)
{
if
(
request
.
isOnlyPanel
())
{
...
...
@@ -93,21 +103,40 @@ public class GroupsController {
return
ResponseEntity
.
ok
(
groupsPanel
);
}
@GetMapping
(
value
=
"/group/status/{groupId}"
,
produces
=
MediaType
.
APPLICATION_OCTET_STREAM_VALUE
)
public
void
downloadStatus
(
@PathVariable
(
"groupId"
)
String
groupId
,
HttpServletResponse
response
)
throws
Exception
{
@GetMapping
(
value
=
"/group/status"
,
produces
=
{
MediaType
.
APPLICATION_OCTET_STREAM_VALUE
,
MediaType
.
APPLICATION_JSON_VALUE
})
public
void
downloadStatus
(
@RequestParam
(
value
=
"groupId"
,
required
=
false
)
String
groupId
,
@RequestParam
(
value
=
"groupName"
,
required
=
false
)
String
groupName
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
Exception
{
if
(
groupId
==
null
&&
groupName
==
null
)
{
response
.
sendError
(
400
,
"Parameter groupId or groupName is required"
);
return
;
}
if
(
groupId
==
null
)
{
GroupEntity
group
=
groupNameService
.
getGroupFromNames
(
Optional
.
of
(
groupName
));
groupId
=
group
.
getId
();
}
List
<
String
[]>
status
=
groupStatusManager
.
generateStatus
(
groupId
);
try
(
OutputStream
out
=
response
.
getOutputStream
();
CSVWriter
writer
=
new
CSVWriter
(
new
OutputStreamWriter
(
out
)))
{
try
(
OutputStream
out
=
response
.
getOutputStream
())
{
writer
.
writeNext
(
new
String
[]{
"program"
,
"email"
});
if
(
"application/json"
.
equals
(
request
.
getHeader
(
"Accept"
)))
{
MAPPER
.
writeValue
(
out
,
status
);
}
else
{
try
(
CSVWriter
writer
=
new
CSVWriter
(
new
OutputStreamWriter
(
out
)))
{
writer
.
writeNext
(
new
String
[]{
"program"
,
"email"
});
for
(
String
[]
row
:
groupStatusManager
.
generateStatus
(
groupId
))
{
writer
.
writeNext
(
row
);
for
(
String
[]
row
:
status
)
{
writer
.
writeNext
(
row
);
}
}
}
}
}
private
<
T
extends
PaginatedModelRequest
&
SearchFilterRequest
>
PaginatedData
<
GroupNode
>
getGroupsPanel
(
GroupEntity
parentGroup
,
T
request
)
{
return
groupsTreeBuilder
.
listSubGroups
(
parentGroup
,
request
,
se
ssion
.
getUserId
());
return
groupsTreeBuilder
.
listSubGroups
(
parentGroup
,
request
,
se
rvletRequest
.
getUserPrincipal
().
getName
());
}
}
gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java
View file @
6eef3264
package
it.inaf.ia2.gms.controller
;
import
it.inaf.ia2.gms.authn.SessionData
;
import
it.inaf.ia2.gms.manager.GroupsManager
;
import
it.inaf.ia2.gms.manager.InvitedRegistrationManager
;
import
it.inaf.ia2.gms.manager.PermissionsManager
;
...
...
@@ -10,6 +9,7 @@ import it.inaf.ia2.gms.model.response.GroupsTabResponse;
import
it.inaf.ia2.gms.persistence.model.GroupEntity
;
import
it.inaf.ia2.gms.service.GroupsService
;
import
it.inaf.ia2.gms.service.GroupsTreeBuilder
;
import
javax.servlet.http.HttpServletRequest
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
...
...
@@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
public
class
GroupsTabResponseBuilder
{
@Autowired
private
SessionData
session
;
HttpServletRequest
servletRequest
;
@Autowired
private
PermissionsManager
permissionsManager
;
...
...
@@ -46,7 +46,7 @@ public class GroupsTabResponseBuilder {
Permission
permission
=
permissionsManager
.
getCurrentUserPermission
(
group
);
response
.
setPermission
(
permission
);
response
.
setGroupsPanel
(
groupsListBuilder
.
listSubGroups
(
group
,
request
,
se
ssion
.
getUserId
()));
response
.
setGroupsPanel
(
groupsListBuilder
.
listSubGroups
(
group
,
request
,
se
rvletRequest
.
getUserPrincipal
().
getName
()));
response
.
setLeaf
(
group
.
isLeaf
());
...
...
gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java
View file @
6eef3264
...
...
@@ -83,6 +83,10 @@ public class HomePageController {
@GetMapping
(
value
=
"/"
,
produces
=
MediaType
.
TEXT_HTML_VALUE
)
public
String
index
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException
,
IOException
{
// This page MUST NOT be cached to avoid losing the login redirect
response
.
setHeader
(
"Cache-Control"
,
"no-store, must-revalidate"
);
response
.
setHeader
(
"Expires"
,
"0"
);
Optional
<
List
<
InvitedRegistration
>>
optReg
=
invitedRegistrationManager
.
completeInvitedRegistrationIfNecessary
();
if
(
optReg
.
isPresent
())
{
request
.
setAttribute
(
"invited-registrations"
,
optReg
.
get
());
...
...
gms/src/main/java/it/inaf/ia2/gms/controller/JWTWebServiceController.java
View file @
6eef3264
...
...
@@ -7,7 +7,6 @@ import it.inaf.ia2.gms.manager.InvitedRegistrationManager;
import
it.inaf.ia2.gms.manager.MembershipManager
;
import
it.inaf.ia2.gms.manager.PermissionsManager
;
import
it.inaf.ia2.gms.model.Permission
;
import
it.inaf.ia2.gms.model.RapUser
;
import
it.inaf.ia2.gms.model.response.UserPermission
;
import
it.inaf.ia2.gms.persistence.GroupsDAO
;
import
it.inaf.ia2.gms.persistence.PermissionsDAO
;
...
...
@@ -19,6 +18,7 @@ import it.inaf.ia2.gms.service.GroupsService;
import
it.inaf.ia2.gms.service.JoinService
;
import
it.inaf.ia2.gms.service.PermissionUtils
;
import
it.inaf.ia2.gms.service.SearchService
;
import
it.inaf.ia2.rap.data.RapUser
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.security.Principal
;
...
...
@@ -39,15 +39,16 @@ import org.springframework.web.bind.annotation.GetMapping;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.PutMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
/**
* Web service called by other web applications using JWT (delegation).
* This class needs some refactoring: it contains all endpoints that used JWT.
* Now all endpoints accept both a JWT token or a session, so some of them could
* be removed and others should be moved on dedicated classes. Some endpoints
* match 2 patters to achieve a smooth transition.
*/
@RestController
@RequestMapping
(
"/ws/jwt"
)
public
class
JWTWebServiceController
{
@Autowired
...
...
@@ -63,7 +64,7 @@ public class JWTWebServiceController {
private
GroupsService
groupsService
;
@Autowired
pr
ivate
GroupNameService
groupNameService
;
pr
otected
GroupNameService
groupNameService
;
@Autowired
private
MembershipManager
membershipManager
;
...
...
@@ -83,7 +84,7 @@ public class JWTWebServiceController {
/**
* This endpoint is compliant with the IVOA GMS standard.
*/
@GetMapping
(
value
=
"/
search"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@GetMapping
(
value
=
{
"/
ws/jwt/search"
,
"/vo/search"
}
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
getGroups
(
HttpServletResponse
response
)
throws
IOException
{
List
<
GroupEntity
>
memberships
=
membershipManager
.
getCurrentUserMemberships
();
...
...
@@ -104,10 +105,10 @@ public class JWTWebServiceController {
* be defined adding ".+", otherwise Spring will think it is a file
* extension (thanks https://stackoverflow.com/a/16333149/771431)
*/
@GetMapping
(
value
=
"
/search/{group:.+}"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@GetMapping
(
value
=
{
"/ws/jwt
/search/{group:.+}"
,
"/vo/search/{group:.+}"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
isMemberOf
(
@PathVariable
(
"group"
)
String
group
,
HttpServletResponse
response
)
throws
IOException
{
List
<
String
>
groupNames
=
extractGroupNames
(
group
);
List
<
String
>
groupNames
=
groupNameService
.
extractGroupNames
(
group
);
boolean
isMember
=
membershipManager
.
isCurrentUserMemberOf
(
"ROOT"
);
if
(!
isMember
)
{
...
...
@@ -135,13 +136,12 @@ public class JWTWebServiceController {
// else: empty response (as defined by GMS standard)
}
@GetMapping
(
value
=
{
"/list/{group:.+}"
,
"/list"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
listGroups
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
,
Principal
principal
,
HttpServletResponse
response
)
throws
IOException
{
@GetMapping
(
value
=
{
"/
ws/jwt/
list/{group:.+}"
,
"/
ws/jwt/
list"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
listGroups
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
Names
,
Principal
principal
,
HttpServletResponse
response
)
throws
IOException
{
String
userId
=
principal
.
getName
();
List
<
String
>
groupNames
=
extractGroupNames
(
group
);
GroupEntity
parentGroup
=
getGroupFromNames
(
groupNames
);
GroupEntity
parentGroup
=
groupNameService
.
getGroupFromNames
(
groupNames
);
List
<
GroupEntity
>
allSubGroups
=
groupsDAO
.
getDirectSubGroups
(
parentGroup
.
getPath
());
...
...
@@ -157,7 +157,7 @@ public class JWTWebServiceController {
try
(
PrintWriter
pw
=
new
PrintWriter
(
response
.
getOutputStream
()))
{
for
(
String
groupName
:
groupNameService
.
getGroupsNames
(
visibleSubgroups
))
{
pw
.
println
(
getShortGroupName
(
groupName
,
group
));
pw
.
println
(
groupNameService
.
getShortGroupName
(
groupName
,
group
Names
));
}
}
}
...
...
@@ -166,10 +166,10 @@ public class JWTWebServiceController {
* Creates a group and its ancestors if they are missing. It doesn't fail if
* the last group already exists.
*/
@PostMapping
(
value
=
"/{group:.+}"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@PostMapping
(
value
=
"/
ws/jwt/
{group:.+}"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
createGroup
(
@PathVariable
(
"group"
)
String
groupParam
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
List
<
String
>
groupNames
=
extractGroupNames
(
groupParam
);
List
<
String
>
groupNames
=
groupNameService
.
extractGroupNames
(
groupParam
);
String
leafParam
=
request
.
getParameter
(
"leaf"
);
boolean
leaf
=
leafParam
==
null
?
false
:
Boolean
.
valueOf
(
leafParam
);
...
...
@@ -191,29 +191,29 @@ public class JWTWebServiceController {
}
}
@DeleteMapping
(
value
=
"/{group:.+}"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@DeleteMapping
(
value
=
"/
ws/jwt/
{group:.+}"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
deleteGroup
(
@PathVariable
(
"group"
)
String
groupParam
,
HttpServletResponse
response
)
{
GroupEntity
group
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
groupParam
));
GroupEntity
group
=
group
NameService
.
ge
tGroup
From
Names
(
Optional
.
of
(
groupParam
));
groupsDAO
.
deleteGroup
(
group
);
response
.
setStatus
(
HttpServletResponse
.
SC_NO_CONTENT
);
}
@GetMapping
(
value
=
{
"/membership/{group:.+}"
,
"/membership"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
getMembership
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
,
@RequestParam
(
"user_id"
)
String
userId
,
HttpServletResponse
response
)
throws
IOException
{
@GetMapping
(
value
=
{
"/
ws/jwt/
membership/{group:.+}"
,
"/
ws/jwt/
membership"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
getMembership
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
Names
,
@RequestParam
(
"user_id"
)
String
userId
,
HttpServletResponse
response
)
throws
IOException
{
GroupEntity
parent
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
group
)
);
GroupEntity
parent
=
group
NameService
.
ge
tGroup
From
Names
(
group
Names
);
List
<
GroupEntity
>
groups
=
membershipManager
.
getUserGroups
(
parent
,
userId
);
try
(
PrintWriter
pw
=
new
PrintWriter
(
response
.
getOutputStream
()))
{
for
(
String
groupName
:
groupNameService
.
getGroupsNames
(
groups
))
{
pw
.
println
(
getShortGroupName
(
groupName
,
group
));
pw
.
println
(
groupNameService
.
getShortGroupName
(
groupName
,
group
Names
));
}
}
}
@PostMapping
(
value
=
{
"/membership/{group:.+}"
,
"/membership"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
addMember
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
@PostMapping
(
value
=
{
"/
ws/jwt/
membership/{group:.+}"
,
"/
ws/jwt/
membership"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
addMember
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
Names
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
String
targetUserId
=
request
.
getParameter
(
"user_id"
);
if
(
targetUserId
==
null
)
{
...
...
@@ -221,64 +221,64 @@ public class JWTWebServiceController {
return
;
}
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
group
)
);
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
group
Names
);
membershipManager
.
addMember
(
groupEntity
,
targetUserId
);
}
@DeleteMapping
(
value
=
{
"/membership/{group:.+}"
,
"/membership"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
removeMember
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
,
@RequestParam
(
"user_id"
)
String
userId
,
@DeleteMapping
(
value
=
{
"/
ws/jwt/
membership/{group:.+}"
,
"/
ws/jwt/
membership"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
removeMember
(
@PathVariable
(
"group"
)
Optional
<
String
>
group
Names
,
@RequestParam
(
"user_id"
)
String
userId
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
group
)
);
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
group
Names
);
membershipManager
.
removeMember
(
groupEntity
,
userId
);
response
.
setStatus
(
HttpServletResponse
.
SC_NO_CONTENT
);
}
@GetMapping
(
value
=
{
"/permission/{group:.+}"
,
"/permission"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@GetMapping
(
value
=
{
"/
ws/jwt/
permission/{group:.+}"
,
"/
ws/jwt/
permission"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
getUserPermission
(
@PathVariable
(
"group"
)
Optional
<
String
>
groupNames
,
@RequestParam
(
"user_id"
)
Optional
<
String
>
userId
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
GroupEntity
groupEntity
=
groupNameService
.
getGroupFromNames
(
groupNames
);
if
(
userId
.
isPresent
())
{
try
(
PrintWriter
pw
=
new
PrintWriter
(
response
.
getOutputStream
()))
{
for
(
UserPermission
userPermission
:
searchService
.
getUserPermission
(
userId
.
get
(),
permissionsManager
.
getCurrentUserPermissions
(
g
etRoot
()
)))
{
for
(
UserPermission
userPermission
:
searchService
.
getUserPermission
(
groupEntity
,
userId
.
get
(),
permissionsManager
.
getCurrentUserPermissions
(
g
roupEntity
)))
{
String
group
=
String
.
join
(
"."
,
userPermission
.
getGroupCompleteName
());
pw
.
println
(
group
+
" "
+
userPermission
.
getPermission
());
}
}
}
else
{
GroupEntity
groupEntity
=
getGroupFromNames
(
extractGroupNames
(
groupNames
));
try
(
PrintWriter
pw
=
new
PrintWriter
(
response
.
getOutputStream
()))
{
for
(
it
.
inaf
.
ia2
.
gms
.
model
.
UserPermission
up
:
permissionsManager
.
getAllPermissions
(
groupEntity
))
{
for
(
it
.
inaf
.
ia2
.
gms
.
model
.
Rap
UserPermission
up
:
permissionsManager
.
getAllPermissions
(
groupEntity
))
{
pw
.
println
(
up
.
getUser
().
getId
()
+
" "
+
up
.
getPermission
());
}
}
}
}
@PostMapping
(
value
=
{
"/permission/{group:.+}"
,
"/permission/"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
,
consumes
=
MediaType
.
APPLICATION_FORM_URLENCODED_VALUE
)
@PostMapping
(
value
=
{
"/
ws/jwt/
permission/{group:.+}"
,
"/
ws/jwt/
permission/"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
,
consumes
=
MediaType
.
APPLICATION_FORM_URLENCODED_VALUE
)
public
void
addPermission
(
@PathVariable
(
"group"
)
Optional
<
String
>
groupNames
,
@RequestParam
(
"user_id"
)
String
targetUserId
,
@RequestParam
(
"permission"
)
Permission
permission
)
throws
IOException
{
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
groupNames
)
)
;
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
groupNames
);
permissionsManager
.
addPermission
(
groupEntity
,
targetUserId
,
permission
);
}
@PutMapping
(
value
=
{
"/permission/{group:.+}"
,
"/permission/"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
,
consumes
=
MediaType
.
APPLICATION_FORM_URLENCODED_VALUE
)
@PutMapping
(
value
=
{
"/
ws/jwt/
permission/{group:.+}"
,
"/
ws/jwt/
permission/"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
,
consumes
=
MediaType
.
APPLICATION_FORM_URLENCODED_VALUE
)
public
void
setPermission
(
@PathVariable
(
"group"
)
Optional
<
String
>
groupNames
,
@RequestParam
(
"user_id"
)
String
targetUserId
,
@RequestParam
(
"permission"
)
Permission
permission
)
throws
IOException
{
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
groupNames
)
)
;
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
groupNames
);
permissionsManager
.
createOrUpdatePermission
(
groupEntity
,
targetUserId
,
permission
);
}
@DeleteMapping
(
value
=
{
"/permission/{group:.+}"
,
"/permission/"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@DeleteMapping
(
value
=
{
"/
ws/jwt/
permission/{group:.+}"
,
"/
ws/jwt/
permission/"
},
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
removePermission
(
@PathVariable
(
"group"
)
Optional
<
String
>
groupNames
,
@RequestParam
(
"user_id"
)
String
userId
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
IOException
{
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
groupNames
)
)
;
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
groupNames
);
permissionsManager
.
removePermission
(
groupEntity
,
userId
);
response
.
setStatus
(
HttpServletResponse
.
SC_NO_CONTENT
);
}
@GetMapping
(
value
=
"/check-invited-registration"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@GetMapping
(
value
=
{
"/ws/jwt/check-invited-registration"
,
"/check-invited-registration"
}
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
completeInvitedRegistrationIfNecessary
(
Principal
principal
,
HttpServletResponse
response
)
throws
IOException
{
String
userId
=
principal
.
getName
();
...
...
@@ -300,7 +300,7 @@ public class JWTWebServiceController {
}
}
@PostMapping
(
value
=
"/invited-registration"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@PostMapping
(
value
=
{
"/ws/jwt/invited-registration"
,
"/invited-registration"
}
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
addInvitedRegistration
(
@RequestParam
(
"token_hash"
)
String
tokenHash
,
@RequestParam
(
"email"
)
String
email
,
@RequestParam
(
"groups"
)
String
groupNamesAndPermissionsParam
,
HttpServletResponse
response
)
{
...
...
@@ -311,7 +311,7 @@ public class JWTWebServiceController {
int
lastSpaceIndex
=
param
.
lastIndexOf
(
" "
);
String
groupName
=
param
.
substring
(
0
,
lastSpaceIndex
);
Permission
permission
=
Permission
.
valueOf
(
param
.
substring
(
lastSpaceIndex
+
1
));
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
groupName
));
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
Optional
.
of
(
groupName
));
groupsPermissions
.
put
(
groupEntity
,
permission
);
}
}
...
...
@@ -321,10 +321,10 @@ public class JWTWebServiceController {
response
.
setStatus
(
HttpServletResponse
.
SC_CREATED
);
}
@GetMapping
(
value
=
"/email/{group:.+}"
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
@GetMapping
(
value
=
{
"/ws/jwt/email/{group:.+}"
,
"/email/{group:.+}"
}
,
produces
=
MediaType
.
TEXT_PLAIN_VALUE
)
public
void
getEmailOfMembers
(
@PathVariable
(
"group"
)
String
groupNames
,
@RequestParam
(
"permission"
)
Optional
<
Permission
>
permission
,
HttpServletResponse
response
)
throws
IOException
{
GroupEntity
groupEntity
=
g
etG
roup
FromNames
(
extrac
tGroupNames
(
groupNames
));
GroupEntity
groupEntity
=
group
NameService
.
ge
tGroup
From
Names
(
Optional
.
of
(
groupNames
));
Set
<
String
>
selectedUserIds
=
null
;
if
(
permission
.
isPresent
())
{
...
...
@@ -340,74 +340,13 @@ public class JWTWebServiceController {
try
(
PrintWriter
pw
=
new
PrintWriter
(
response
.
getOutputStream
()))
{
for
(
RapUser
member
:
membershipManager
.
getMembers
(
groupEntity
))
{
if
(
selectedUserIds
==
null
||
selectedUserIds
.
contains
(
member
.
getId
()))
{
pw
.
println
(
member
.
getPrimaryEmail
());
pw
.
println
(
member
.
getPrimaryEmail
Address
());
}
}
}
}
private
GroupEntity
getGroupFromNames
(
List
<
String
>
groupNames
)
{
if
(
groupNames
.
isEmpty
())
{
return
getRoot
();
}
return
getGroupFromNamesAndIndex
(
groupNames
,
groupNames
.
size
()
-
1
);
}
private
GroupEntity
getGroupFromNamesAndIndex
(
List
<
String
>
groupNames
,
int
index
)
{
String
parentPath
=
""
;
// starting from ROOT
GroupEntity
group
=
null
;
for
(
int
i
=
0
;
i
<
index
+
1
;
i
++)
{
String
groupName
=
groupNames
.
get
(
i
);
group
=
groupsDAO
.
findGroupByParentAndName
(
parentPath
,
groupName
)
.
orElseThrow
(()
->
new
BadRequestException
(
"Unable to find group "
+
groupName
));
parentPath
=
group
.
getPath
();
}
if
(
group
==
null
)
{
throw
new
IllegalStateException
();
}
return
group
;
}
private
GroupEntity
getRoot
()
{
return
groupsDAO
.
findGroupById
(
"ROOT"
)
.
orElseThrow
(()
->
new
IllegalStateException
(
"Missing root group"
));
}
private
List
<
String
>
extractGroupNames
(
Optional
<
String
>
group
)
{
return
extractGroupNames
(
group
.
orElse
(
null
));
}
private
List
<
String
>
extractGroupNames
(
String
groupStr
)
{
if
(
groupStr
==
null
||
groupStr
.
isEmpty
())
{
return
new
ArrayList
<>();
}
List
<
String
>
names
=
new
ArrayList
<>();
String
currentName
=
""
;
for
(
int
i
=
0
;
i
<
groupStr
.
length
();
i
++)
{
char
c
=
groupStr
.
charAt
(
i
);
// dot is the group separator and it must be escaped if used inside
// group names
if
(
c
==
'.'
&&
groupStr
.
charAt
(
i
-
1
)
!=
'\\'
)
{
names
.
add
(
currentName
.
replace
(
"\\."
,
"."
));
currentName
=
""
;
}
else
{
currentName
+=
c
;
}
}
names
.
add
(
currentName
);
return
names
;
}
private
String
getShortGroupName
(
String
completeGroupName
,
Optional
<
String
>
groupPrefix
)
{
if
(
groupPrefix
.
isPresent
())
{
return
completeGroupName
.
substring
(
groupPrefix
.
get
().
length
()
+
1
);
}
return
completeGroupName
;
}
@PostMapping
(
value
=
"/join"
,
produces
=
MediaType
.
APPLICATION_JSON_VALUE
)
@PostMapping
(
value
=
{
"/ws/jwt/join"
,
"/join"
},
produces
=
MediaType
.
APPLICATION_JSON_VALUE
)
public
ResponseEntity
<?>
join
(
RapPrincipal
principal
)
{
String
fromUser
=
principal
.
getName
();
...
...
gms/src/main/java/it/inaf/ia2/gms/controller/KeepAliveController.java
View file @
6eef3264
package
it.inaf.ia2.gms.controller
;
import
it.inaf.ia2.aa.ServiceLocator
;
import
it.inaf.ia2.aa.UserManager
;
import
it.inaf.ia2.gms.authn.SessionData
;
import
it.inaf.ia2.gms.rap.RapClient
;
import
java.util.HashMap
;
import
javax.servlet.http.HttpServletRequest
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -19,14 +21,17 @@ public class KeepAliveController {
@Autowired
private
SessionData
sessionData
;
@Autowired
private
RapClient
rapClient
;
private
final
UserManager
userManager
;
public
KeepAliveController
()
{
userManager
=
ServiceLocator
.
getInstance
().
getUserManager
();
}
@GetMapping
(
value
=
"/keepAlive"
,
produces
=
MediaType
.
APPLICATION_JSON_VALUE
)
public
ResponseEntity
<?>
keepAlive
()
{
public
ResponseEntity
<?>
keepAlive
(
HttpServletRequest
request
)
{
LOG
.
trace
(
"Keepalive called"
);
if
(
sessionData
.
getExpiresIn
()
<
60
)
{
rapClient
.
refreshToken
();
sessionData
.
setUser
(
userManager
.
refreshToken
(
request
)
);
LOG
.
trace
(
"RAP token refreshed"
);
}
// empty JSON object response
...
...
gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java
View file @
6eef3264
...
...
@@ -4,12 +4,12 @@ import it.inaf.ia2.gms.manager.MembershipManager;
import
it.inaf.ia2.gms.manager.PermissionsManager
;
import
it.inaf.ia2.gms.model.request.AddMemberRequest
;
import
it.inaf.ia2.gms.model.response.PaginatedData
;
import
it.inaf.ia2.gms.model.RapUser
;
import
it.inaf.ia2.gms.model.request.PaginatedModelRequest
;
import
it.inaf.ia2.gms.model.request.RemoveMemberRequest
;
import
it.inaf.ia2.gms.model.request.TabRequest
;
import
it.inaf.ia2.gms.persistence.model.GroupEntity
;
import
it.inaf.ia2.gms.service.GroupsService
;
import
it.inaf.ia2.rap.data.RapUser
;
import
java.util.Collections
;
import
java.util.List
;
import
javax.validation.Valid
;
...
...
Prev
1
2
3
4
5
Next