]> source.dussan.org Git - archiva.git/blob
3e9c2dcd3ef4f6ba600060b0065df10ed49eaa1c
[archiva.git] /
1 package org.apache.archiva.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 org.apache.archiva.redback.policy.AccountLockedException;
23 import org.apache.archiva.redback.policy.UserSecurityPolicy;
24 import org.apache.archiva.redback.rbac.Permission;
25 import org.apache.archiva.redback.rbac.RBACManager;
26 import org.apache.archiva.redback.rbac.RbacManagerException;
27 import org.apache.archiva.redback.rbac.UserAssignment;
28 import org.apache.archiva.redback.users.User;
29 import org.apache.archiva.redback.users.UserManager;
30 import org.apache.archiva.redback.users.UserNotFoundException;
31 import org.jsecurity.authc.AuthenticationException;
32 import org.jsecurity.authc.AuthenticationInfo;
33 import org.jsecurity.authc.AuthenticationToken;
34 import org.jsecurity.authc.SimpleAuthenticationInfo;
35 import org.jsecurity.authc.UsernamePasswordToken;
36 import org.jsecurity.authc.credential.CredentialsMatcher;
37 import org.jsecurity.authz.AuthorizationInfo;
38 import org.jsecurity.authz.SimpleAuthorizationInfo;
39 import org.jsecurity.realm.AuthorizingRealm;
40 import org.jsecurity.subject.PrincipalCollection;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import java.util.HashSet;
45 import java.util.Iterator;
46 import java.util.Set;
47
48 public class RedbackRealm
49     extends AuthorizingRealm
50 {
51     private Logger log = LoggerFactory.getLogger( RedbackRealm.class );
52
53     private final UserManager userManager;
54
55     private final RBACManager rbacManager;
56
57     private final UserSecurityPolicy securityPolicy;
58
59     public RedbackRealm( UserManager userManager, RBACManager rbacManager, UserSecurityPolicy securityPolicy )
60     {
61         this.userManager = userManager;
62         this.rbacManager = rbacManager;
63         this.securityPolicy = securityPolicy;
64     }
65
66     @Override
67     protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals )
68     {
69         final String username = (String) principals.fromRealm( getName() ).iterator().next();
70
71         try
72         {
73             final UserAssignment assignment = rbacManager.getUserAssignment( username );
74             final Set<String> roleNames = new HashSet<String>( assignment.getRoleNames() );
75             final Set<String> permissions = new HashSet<String>();
76
77             for ( Iterator<Permission> it = rbacManager.getAssignedPermissions( username ).iterator(); it.hasNext(); )
78             {
79                 Permission permission = it.next();
80                 permissions.add( permission.getName() );
81             }
82
83             SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo( roleNames );
84             authorizationInfo.setStringPermissions( permissions );
85
86             return authorizationInfo;
87         }
88         catch ( RbacManagerException e )
89         {
90             log.error( "Could not authenticate against data source", e );
91         }
92
93         return null;
94     }
95
96     @Override
97     protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token )
98         throws AuthenticationException
99     {
100         if ( token == null )
101         {
102             throw new AuthenticationException( "AuthenticationToken cannot be null" );
103         }
104
105         final UsernamePasswordToken passwordToken = (UsernamePasswordToken) token;
106
107         User user = null;
108         try
109         {
110             user = userManager.findUser( passwordToken.getUsername() );
111         }
112         catch ( UserNotFoundException e )
113         {
114             log.error( "Could not find user " + passwordToken.getUsername() );
115         }
116
117         if ( user == null )
118         {
119             return null;
120         }
121
122         if ( user.isLocked() && !user.isPasswordChangeRequired() )
123         {
124             throw new PrincipalLockedException( "User " + user.getPrincipal() + " is locked." );
125         }
126
127         if ( user.isPasswordChangeRequired() )
128         {
129             throw new PrincipalPasswordChangeRequiredException(
130                 "Password change is required for user " + user.getPrincipal() );
131         }
132
133         return new RedbackAuthenticationInfo( user, getName() );
134     }
135
136     @Override
137     public CredentialsMatcher getCredentialsMatcher()
138     {
139         return new CredentialsMatcher()
140         {
141             public boolean doCredentialsMatch( AuthenticationToken token, AuthenticationInfo info )
142             {
143                 final String credentials = new String( (char[]) token.getCredentials() );
144                 final boolean match = securityPolicy.getPasswordEncoder().encodePassword( credentials ).equals(
145                     (String) info.getCredentials() );
146                 if ( !match )
147                 {
148                     User user = ( (RedbackAuthenticationInfo) info ).getUser();
149                     try
150                     {
151                         securityPolicy.extensionExcessiveLoginAttempts( user );
152                     }
153                     catch ( AccountLockedException e )
154                     {
155                         log.info( "User{} has been locked", user.getUsername(), e );
156                     }
157                     finally
158                     {
159                         try
160                         {
161                             userManager.updateUser( user );
162                         }
163                         catch ( UserNotFoundException e )
164                         {
165                             log.error( "The user to be updated could not be found", e );
166                         }
167                     }
168                 }
169                 return match;
170             }
171         };
172     }
173
174     final class RedbackAuthenticationInfo
175         extends SimpleAuthenticationInfo
176     {
177         private final User user;
178
179         public RedbackAuthenticationInfo( User user, String realmName )
180         {
181             super( user.getPrincipal(), user.getEncodedPassword(), realmName );
182             this.user = user;
183         }
184
185         public User getUser()
186         {
187             return user;
188         }
189     }
190 }