View Javadoc
1   package fr.ifremer.quadrige3.core.security;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Client Core
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import com.google.common.collect.Lists;
27  import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
28  import fr.ifremer.quadrige3.core.service.ClientServiceLocator;
29  import org.apache.commons.collections4.CollectionUtils;
30  import org.apache.commons.lang3.StringUtils;
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
34  import org.springframework.security.core.Authentication;
35  import org.springframework.security.core.AuthenticationException;
36  import org.springframework.security.core.context.SecurityContextHolder;
37  
38  import java.util.Collection;
39  import java.util.Collections;
40  import java.util.List;
41  
42  /**
43   * helper class to handle Spring Security Context
44   *
45   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
46   */
47  public class SecurityContextHelper {
48  
49      private static final Log LOG = LogFactory.getLog(SecurityContextHelper.class);
50  
51      /**
52       * <p>getAuthentication.</p>
53       *
54       * @return a {@link org.springframework.security.core.Authentication} object.
55       */
56      public static Authentication getAuthentication() {
57          return SecurityContextHolder.getContext().getAuthentication();
58      }
59  
60      /**
61       * Clear authentication in Spring context
62       */
63      public static void clear() {
64          SecurityContextHolder.clearContext();
65      }
66  
67      /**
68       * get the current authenticated user
69       *
70       * @return the user if correctly authenticated or null
71       */
72      public static QuadrigeUserDetails getQuadrigeUser() {
73          Authentication authentication = getAuthentication();
74          if (authentication == null || authentication.getPrincipal() == null) {
75              return null;
76          }
77          Object principal = authentication.getPrincipal();
78          if (principal instanceof QuadrigeUserDetails) {
79              return (QuadrigeUserDetails) principal;
80          }
81          return null;
82      }
83  
84      public static int getQuadrigeUserId() {
85          QuadrigeUserDetails quadrigeUser = getQuadrigeUser();
86          if (quadrigeUser == null) {
87              throw new QuadrigeTechnicalException("No Authenticated Quadrige User");
88          }
89          return quadrigeUser.getUserId();
90      }
91  
92     /**
93       * try to authenticate the user by its login
94       *
95       * @param login the user login
96       * @param password the user password
97       * @return true if correctly authenticated
98       */
99      public static boolean authenticate(String login, String password) {
100         if (StringUtils.isBlank(password)) {
101 
102             // Reset
103             password = StringUtils.EMPTY;
104         }
105         else {
106 
107             // Encrypt password
108             password = Encryption.sha(password);
109         }
110 
111         Authentication authentication = new UsernamePasswordAuthenticationToken(login, password);
112         try {
113             if (LOG.isDebugEnabled()) {
114                 LOG.debug("try to authenticate '" + login + "' in local database");
115             }
116 
117             authentication = ClientServiceLocator.instance().getAuthenticationManager().authenticate(authentication);
118 
119             if (LOG.isDebugEnabled()) {
120                 LOG.debug("database authentication successful");
121             }
122         } catch (AuthenticationException ae) {
123             authentication.setAuthenticated(false);
124             if (LOG.isDebugEnabled()) {
125                 LOG.debug("database authentication failed : " + ae.getLocalizedMessage());
126             }
127         }
128         SecurityContextHolder.getContext().setAuthentication(authentication);
129         return authentication.isAuthenticated();
130     }
131 
132     /**
133      * <p>hasAuthority.</p>
134      *
135      * @param authority a {@link QuadrigeUserAuthority} object.
136      * @return a boolean.
137      */
138     public static boolean hasAuthority(QuadrigeUserAuthority authority) {
139         return hasAuthority(getAuthentication(), authority);
140     }
141 
142     /**
143      * <p>hasAuthority.</p>
144      *
145      * @param authorities a {@link List} object.
146      * @return a boolean.
147      */
148     public static boolean hasAuthority(List<QuadrigeUserAuthority> authorities) {
149         return hasAuthority(getAuthentication(), authorities);
150     }
151 
152     /**
153      * <p>hasAuthority.</p>
154      *
155      * @param authentication a {@link org.springframework.security.core.Authentication} object.
156      * @param authorities a {@link Object} object.
157      * @return a boolean.
158      */
159     @SuppressWarnings("unchecked")
160     public static boolean hasAuthority(Authentication authentication, Object authorities) {
161 
162         if (authentication == null || CollectionUtils.isEmpty(authentication.getAuthorities()) || authorities == null) {
163             return false;
164         }
165 
166         List<QuadrigeUserAuthority> authList = Lists.newArrayList();
167         if (authorities instanceof Collection) {
168             authList.addAll((Collection<? extends QuadrigeUserAuthority>) authorities);
169         }
170         else if (authorities instanceof QuadrigeUserAuthority) {
171             authList.add((QuadrigeUserAuthority) authorities);
172         }
173         else {
174             LOG.error("the 'authorities' object is not a QuadrigeUserAuthority and not a Collection<QuadrigeUserAuthority>");
175             return false;
176         }
177 
178         // remove from this list all authorities not contained in authenticated user authorities list
179         authList.retainAll(authentication.getAuthorities());
180 
181         // return true if the user has one or more needed authorities, else otherwise
182         return !authList.isEmpty();
183 
184     }
185 
186     /**
187      * <p>hasMinimumAuthority.</p>
188      *
189      * @param authority a {@link QuadrigeUserAuthority} object.
190      * @return a boolean.
191      */
192     public static boolean hasMinimumAuthority(QuadrigeUserAuthority authority) {
193 
194         return hasMinimumAuthority(getAuthentication(), authority);
195     }
196 
197 
198     /**
199      * <p>hasMinimumAuthority.</p>
200      *
201      * @param authentication a {@link org.springframework.security.core.Authentication} object.
202      * @param authorities a {@link Object} object.
203      * @return a boolean.
204      */
205     @SuppressWarnings("unchecked")
206     public static boolean hasMinimumAuthority(Authentication authentication, Object authorities) {
207 
208         if (authentication == null || CollectionUtils.isEmpty(authentication.getAuthorities()) || authorities == null) {
209             return false;
210         }
211 
212         List<QuadrigeUserAuthority> miniAuthList = Lists.newArrayList();
213         if (authorities instanceof Collection) {
214             miniAuthList.addAll((Collection<? extends QuadrigeUserAuthority>) authorities);
215         }
216         else if (authorities instanceof QuadrigeUserAuthority) {
217             miniAuthList.add((QuadrigeUserAuthority) authorities);
218         }
219         else {
220             LOG.error("the 'authorities' object is not a QuadrigeUserAuthority and not a Collection<QuadrigeUserAuthority>");
221             return false;
222         }
223 
224         // sort by level
225         Collections.sort(miniAuthList);
226 
227         // get the highest level (the last item)
228         QuadrigeUserAuthority minimumAuthority = miniAuthList.get(miniAuthList.size() - 1);
229 
230         List<QuadrigeUserAuthority> userAuthorities = (List<QuadrigeUserAuthority>) authentication.getAuthorities();
231         for (QuadrigeUserAuthority userAuthority : userAuthorities) {
232             if (userAuthority.compareTo(minimumAuthority) >= 0) {
233                 return true;
234             }
235         }
236 
237         return false;
238     }
239 
240 }