]> source.dussan.org Git - archiva.git/blob
fd43d4aeeec606a0dbd61b486b5c3b6ca986fbb4
[archiva.git] /
1 package org.codehaus.redback.jsecurity;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.Set;
25
26 import org.apache.archiva.redback.users.User;
27 import org.apache.archiva.redback.users.UserNotFoundException;
28 import org.codehaus.plexus.redback.policy.AccountLockedException;
29 import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
30 import org.codehaus.plexus.redback.rbac.Permission;
31 import org.codehaus.plexus.redback.rbac.RBACManager;
32 import org.codehaus.plexus.redback.rbac.RbacManagerException;
33 import org.codehaus.plexus.redback.rbac.UserAssignment;
34 import org.apache.archiva.redback.users.UserManager;
35 import org.jsecurity.authc.AuthenticationException;
36 import org.jsecurity.authc.AuthenticationInfo;
37 import org.jsecurity.authc.AuthenticationToken;
38 import org.jsecurity.authc.SimpleAuthenticationInfo;
39 import org.jsecurity.authc.UsernamePasswordToken;
40 import org.jsecurity.authc.credential.CredentialsMatcher;
41 import org.jsecurity.authz.AuthorizationInfo;
42 import org.jsecurity.authz.SimpleAuthorizationInfo;
43 import org.jsecurity.realm.AuthorizingRealm;
44 import org.jsecurity.subject.PrincipalCollection;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public class RedbackRealm extends AuthorizingRealm
49 {
50     private Logger log = LoggerFactory.getLogger(RedbackRealm.class);
51
52     private final UserManager userManager;
53
54     private final RBACManager rbacManager;
55
56     private final UserSecurityPolicy securityPolicy;
57
58     public RedbackRealm(UserManager userManager, RBACManager rbacManager, UserSecurityPolicy securityPolicy)
59     {
60         this.userManager = userManager;
61         this.rbacManager = rbacManager;
62         this.securityPolicy = securityPolicy;
63     }
64     
65     @Override
66     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
67     {
68         final String username = (String) principals.fromRealm(getName()).iterator().next();
69
70         try
71         {
72             final UserAssignment assignment = rbacManager.getUserAssignment(username);
73             final Set<String> roleNames = new HashSet<String>(assignment.getRoleNames());
74             final Set<String> permissions = new HashSet<String>();
75
76             for (Iterator<Permission> it = rbacManager.getAssignedPermissions(username).iterator(); it.hasNext();)
77             {
78                 Permission permission = it.next();
79                 permissions.add(permission.getName());
80             }
81
82             SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roleNames);
83             authorizationInfo.setStringPermissions(permissions);
84
85             return authorizationInfo;
86         }
87         catch (RbacManagerException e)
88         {
89             log.error("Could not authenticate against data source", e);
90         }
91         
92         return null;
93     }
94
95     @Override
96     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
97         throws AuthenticationException
98     {
99         if (token == null)
100         {
101             throw new AuthenticationException("AuthenticationToken cannot be null");
102         }
103         
104         final UsernamePasswordToken passwordToken = (UsernamePasswordToken)token;
105
106         User user = null;
107         try
108         {
109             user = userManager.findUser(passwordToken.getUsername());
110         }
111         catch (UserNotFoundException e)
112         {
113             log.error("Could not find user " + passwordToken.getUsername());
114         }
115
116         if (user == null)
117         {
118             return null;
119         }
120
121         if ( user.isLocked() && !user.isPasswordChangeRequired() )
122         {
123             throw new PrincipalLockedException("User " + user.getPrincipal() + " is locked.");
124         }
125
126         if ( user.isPasswordChangeRequired() )
127         {
128             throw new PrincipalPasswordChangeRequiredException("Password change is required for user " + user.getPrincipal());
129         }
130
131         return new RedbackAuthenticationInfo(user, getName());
132     }
133
134     @Override
135     public CredentialsMatcher getCredentialsMatcher()
136     {
137         return new CredentialsMatcher()
138         {
139             public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info)
140             {
141                 final String credentials = new String((char[])token.getCredentials());
142                 final boolean match = securityPolicy.getPasswordEncoder().encodePassword(credentials).equals((String)info.getCredentials());
143                 if (!match)
144                 {
145                     User user = ((RedbackAuthenticationInfo)info).getUser();
146                     try
147                     {
148                         securityPolicy.extensionExcessiveLoginAttempts( user );
149                     }
150                     catch (AccountLockedException e)
151                     {
152                         log.info("User{} has been locked", user.getUsername(), e);
153                     }
154                     finally
155                     {
156                         try
157                         {
158                             userManager.updateUser( user );
159                         }
160                         catch (UserNotFoundException e)
161                         {
162                             log.error("The user to be updated could not be found", e);
163                         }
164                     }
165                 }
166                 return match;
167             }
168         };
169     }
170
171     final class RedbackAuthenticationInfo extends SimpleAuthenticationInfo
172     {
173         private final User user;
174
175         public RedbackAuthenticationInfo(User user, String realmName)
176         {
177             super(user.getPrincipal(), user.getEncodedPassword(), realmName);
178             this.user = user;
179         }
180
181         public User getUser()
182         {
183             return user;
184         }
185     }
186 }