2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.service
;
11 import java
.util
.EnumSet
;
13 import org
.apache
.log4j
.Logger
;
14 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
15 import org
.springframework
.beans
.factory
.annotation
.Qualifier
;
16 import org
.springframework
.security
.authentication
.AnonymousAuthenticationToken
;
17 import org
.springframework
.security
.authentication
.AuthenticationProvider
;
18 import org
.springframework
.security
.core
.Authentication
;
19 import org
.springframework
.security
.core
.context
.SecurityContext
;
20 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
21 import org
.springframework
.security
.core
.userdetails
.UserDetails
;
22 import org
.springframework
.security
.web
.authentication
.preauth
.PreAuthenticatedAuthenticationToken
;
24 import com
.vaadin
.spring
.annotation
.SpringComponent
;
25 import com
.vaadin
.spring
.annotation
.UIScope
;
27 import eu
.etaxonomy
.cdm
.api
.application
.CdmRepository
;
28 import eu
.etaxonomy
.cdm
.api
.application
.RunAsAuthenticator
;
29 import eu
.etaxonomy
.cdm
.database
.PermissionDeniedException
;
30 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
31 import eu
.etaxonomy
.cdm
.model
.common
.User
;
32 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
33 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CdmAuthority
;
34 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CdmAuthorityParsingException
;
35 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.ICdmPermissionEvaluator
;
36 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Role
;
37 import eu
.etaxonomy
.cdm
.vaadin
.security
.RolesAndPermissions
;
38 import eu
.etaxonomy
.cdm
.vaadin
.security
.VaadinUserHelper
;
41 * @author a.kohlbecker
47 public class CdmUserHelper
extends VaadinUserHelper
{
49 public static final Logger logger
= Logger
.getLogger(CdmUserHelper
.class);
52 private ICdmPermissionEvaluator permissionEvaluator
;
55 @Qualifier("cdmRepository")
56 private CdmRepository repo
;
59 @Qualifier("runAsAuthenticationProvider")
60 AuthenticationProvider runAsAuthenticationProvider
;
62 RunAsAuthenticator runAsAutheticator
= new RunAsAuthenticator();
64 public CdmUserHelper(){
66 runAsAutheticator
.setRunAsAuthenticationProvider(runAsAuthenticationProvider
);
71 public boolean userIsAutheticated() {
72 Authentication authentication
= getAuthentication();
73 if(authentication
!= null){
74 return authentication
.isAuthenticated();
81 public boolean userIsAnnonymous() {
82 Authentication authentication
= getAuthentication();
83 return authentication
!= null
84 && authentication
.isAuthenticated()
85 && authentication
instanceof AnonymousAuthenticationToken
;
89 public String
userName() {
90 Authentication authentication
= getAuthentication();
91 if(authentication
!= null) {
92 return authentication
.getName();
98 public boolean userIsAdmin() {
99 Authentication authentication
= getAuthentication();
100 if(authentication
!= null) {
101 return authentication
.getAuthorities().stream().anyMatch(a
-> {
102 return a
.getAuthority().equals(Role
.ROLE_ADMIN
.getAuthority());
109 public boolean userIsRegistrationCurator() {
110 Authentication authentication
= getAuthentication();
111 if(authentication
!= null) {
112 return authentication
.getAuthorities().stream().anyMatch(a
-> {
113 return a
.equals(RolesAndPermissions
.ROLE_CURATION
)
114 // doing faster regex check here instreas of using CdmAuthoritiy.fromString()
115 || a
.getAuthority().matches("^Registration\\.\\[.*UPDATE");
122 public boolean userHasPermission(CdmBase entity
, Object
... args
){
123 EnumSet
<CRUD
> crudSet
= crudSetFromArgs(args
);
125 return permissionEvaluator
.hasPermission(getAuthentication(), entity
, crudSet
);
126 } catch (PermissionDeniedException e
){
133 public boolean userHasPermission(Class
<?
extends CdmBase
> cdmType
, Integer entitiyId
, Object
... args
){
134 EnumSet
<CRUD
> crudSet
= crudSetFromArgs(args
);
136 CdmBase entity
= repo
.getCommonService().find(cdmType
, entitiyId
);
137 return permissionEvaluator
.hasPermission(getAuthentication(), entity
, crudSet
);
138 } catch (PermissionDeniedException e
){
145 public boolean userHasPermission(Class
<?
extends CdmBase
> cdmType
, Object
... args
){
146 EnumSet
<CRUD
> crudSet
= crudSetFromArgs(args
);
148 return permissionEvaluator
.hasPermission(getAuthentication(), cdmType
, crudSet
);
149 } catch (PermissionDeniedException e
){
155 public void logout() {
156 SecurityContext context
= SecurityContextHolder
.getContext();
157 context
.setAuthentication(null);
158 SecurityContextHolder
.clearContext();
162 private EnumSet
<CRUD
> crudSetFromArgs(Object
[] args
) {
163 EnumSet
<CRUD
> crudSet
= EnumSet
.noneOf(CRUD
.class);
164 for(int i
= 0; i
< args
.length
; i
++){
166 crudSet
.add(CRUD
.valueOf(args
[i
].toString()));
167 } catch (Exception e
){
168 throw new IllegalArgumentException("could not add " + args
[i
], e
);
178 * FIXME is it ok to use the SecurityContextHolder or do we need to hold the context in the vaadin session?
180 private SecurityContext
currentSecurityContext() {
181 return SecurityContextHolder
.getContext();
187 private Authentication
getAuthentication() {
188 return currentSecurityContext().getAuthentication();
195 public void createAuthorityFor(String username
, CdmBase cdmEntity
, EnumSet
<CRUD
> crud
, String property
) {
196 UserDetails userDetails
= repo
.getUserService().loadUserByUsername(username
);
197 if(userDetails
!= null){
198 runAsAutheticator
.runAsAuthentication(Role
.ROLE_USER_MANAGER
);
199 User user
= (User
)userDetails
;
200 CdmAuthority authority
= new CdmAuthority(cdmEntity
, property
, crud
);
202 user
.getGrantedAuthorities().add(authority
.asNewGrantedAuthority());
203 } catch (CdmAuthorityParsingException e
) {
204 throw new RuntimeException(e
);
206 repo
.getSession().flush();
207 runAsAutheticator
.restoreAuthentication();
208 logger
.debug("new authority for " + username
+ ": " + authority
.toString());
209 Authentication authentication
= new PreAuthenticatedAuthenticationToken(user
, user
.getPassword(), user
.getAuthorities());
210 SecurityContextHolder
.getContext().setAuthentication(authentication
);
211 logger
.debug("security context refreshed with user " + username
);
224 public void createAuthorityFor(String username
, Class
<?
extends CdmBase
> cdmType
, Integer entitiyId
, EnumSet
<CRUD
> crud
, String property
) {
226 CdmBase cdmEntity
= repo
.getCommonService().find(cdmType
, entitiyId
);
228 createAuthorityFor(username
,cdmEntity
, crud
, property
);
235 public void createAuthorityForCurrentUser(CdmBase cdmEntity
, EnumSet
<CRUD
> crud
, String property
) {
236 createAuthorityFor(userName(), cdmEntity
, crud
, property
);
247 public void createAuthorityForCurrentUser(Class
<?
extends CdmBase
> cdmType
, Integer entitiyId
, EnumSet
<CRUD
> crud
, String property
) {
248 createAuthorityFor(userName(), cdmType
, entitiyId
, crud
, property
);