001    package org.apache.archiva.security;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.archiva.admin.model.RepositoryAdminException;
023    import org.apache.archiva.admin.model.beans.ManagedRepository;
024    import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
025    import org.apache.archiva.redback.authentication.AuthenticationResult;
026    import org.apache.archiva.redback.authorization.AuthorizationException;
027    import org.apache.archiva.redback.role.RoleManager;
028    import org.apache.archiva.redback.role.RoleManagerException;
029    import org.apache.archiva.redback.system.DefaultSecuritySession;
030    import org.apache.archiva.redback.system.SecuritySession;
031    import org.apache.archiva.redback.system.SecuritySystem;
032    import org.apache.archiva.redback.users.User;
033    import org.apache.archiva.redback.users.UserManagerException;
034    import org.apache.archiva.redback.users.UserNotFoundException;
035    import org.apache.archiva.security.common.ArchivaRoleConstants;
036    import org.slf4j.Logger;
037    import org.slf4j.LoggerFactory;
038    import org.springframework.stereotype.Service;
039    
040    import javax.inject.Inject;
041    import java.util.ArrayList;
042    import java.util.List;
043    
044    /**
045     * DefaultUserRepositories
046     */
047    @Service( "userRepositories" )
048    public class DefaultUserRepositories
049        implements UserRepositories
050    {
051    
052        @Inject
053        private SecuritySystem securitySystem;
054    
055        @Inject
056        private RoleManager roleManager;
057    
058        @Inject
059        private ManagedRepositoryAdmin managedRepositoryAdmin;
060    
061        private Logger log = LoggerFactory.getLogger( getClass() );
062    
063        public List<String> getObservableRepositoryIds( String principal )
064            throws PrincipalNotFoundException, AccessDeniedException, ArchivaSecurityException
065        {
066            String operation = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
067    
068            return getAccessibleRepositoryIds( principal, operation );
069        }
070    
071        public List<String> getManagableRepositoryIds( String principal )
072            throws PrincipalNotFoundException, AccessDeniedException, ArchivaSecurityException
073        {
074            String operation = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
075    
076            return getAccessibleRepositoryIds( principal, operation );
077        }
078    
079        private List<String> getAccessibleRepositoryIds( String principal, String operation )
080            throws ArchivaSecurityException, AccessDeniedException, PrincipalNotFoundException
081        {
082    
083            List<ManagedRepository> managedRepositories = getAccessibleRepositories( principal, operation );
084            List<String> repoIds = new ArrayList<String>( managedRepositories.size() );
085            for ( ManagedRepository managedRepository : managedRepositories )
086            {
087                repoIds.add( managedRepository.getId() );
088            }
089    
090            return repoIds;
091        }
092    
093        public List<ManagedRepository> getAccessibleRepositories( String principal )
094            throws ArchivaSecurityException, AccessDeniedException, PrincipalNotFoundException
095        {
096            return getAccessibleRepositories( principal, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
097        }
098    
099        private List<ManagedRepository> getAccessibleRepositories( String principal, String operation )
100            throws ArchivaSecurityException, AccessDeniedException, PrincipalNotFoundException
101        {
102            SecuritySession securitySession = createSession( principal );
103    
104            List<ManagedRepository> managedRepositories = new ArrayList<ManagedRepository>();
105    
106            try
107            {
108                List<ManagedRepository> repos = managedRepositoryAdmin.getManagedRepositories();
109    
110                for ( ManagedRepository repo : repos )
111                {
112                    try
113                    {
114                        String repoId = repo.getId();
115                        if ( securitySystem.isAuthorized( securitySession, operation, repoId ) )
116                        {
117                            managedRepositories.add( repo );
118                        }
119                    }
120                    catch ( AuthorizationException e )
121                    {
122                        // swallow.
123    
124                        log.debug( "Not authorizing '{}' for repository '{}': {}", principal, repo.getId(),
125                                   e.getMessage() );
126    
127                    }
128                }
129    
130                return managedRepositories;
131            }
132            catch ( RepositoryAdminException e )
133            {
134                throw new ArchivaSecurityException( e.getMessage(), e );
135            }
136        }
137    
138        private SecuritySession createSession( String principal )
139            throws ArchivaSecurityException, AccessDeniedException
140        {
141            User user;
142            try
143            {
144                user = securitySystem.getUserManager().findUser( principal );
145                if ( user == null )
146                {
147                    throw new ArchivaSecurityException(
148                        "The security system had an internal error - please check your system logs" );
149                }
150            }
151            catch ( UserNotFoundException e )
152            {
153                throw new PrincipalNotFoundException( "Unable to find principal " + principal + "", e );
154            }
155            catch ( UserManagerException e )
156            {
157                throw new ArchivaSecurityException( e.getMessage(), e );
158            }
159    
160            if ( user.isLocked() )
161            {
162                throw new AccessDeniedException( "User " + principal + "(" + user.getFullName() + ") is locked." );
163            }
164    
165            AuthenticationResult authn = new AuthenticationResult( true, principal, null );
166            authn.setUser( user );
167            return new DefaultSecuritySession( authn, user );
168        }
169    
170        public void createMissingRepositoryRoles( String repoId )
171            throws ArchivaSecurityException
172        {
173            try
174            {
175                if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId ) )
176                {
177                    roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId );
178                }
179    
180                if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId ) )
181                {
182                    roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId );
183                }
184            }
185            catch ( RoleManagerException e )
186            {
187                throw new ArchivaSecurityException( "Unable to create roles for configured repositories: " + e.getMessage(),
188                                                    e );
189            }
190        }
191    
192        public boolean isAuthorizedToUploadArtifacts( String principal, String repoId )
193            throws PrincipalNotFoundException, ArchivaSecurityException
194        {
195            try
196            {
197                SecuritySession securitySession = createSession( principal );
198    
199                return securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
200                                                    repoId );
201    
202            }
203            catch ( AuthorizationException e )
204            {
205                throw new ArchivaSecurityException( e.getMessage(), e);
206            }
207        }
208    
209        public boolean isAuthorizedToDeleteArtifacts( String principal, String repoId )
210            throws ArchivaSecurityException
211        {
212            try
213            {
214                SecuritySession securitySession = createSession( principal );
215    
216                return securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_DELETE,
217                                                    repoId );
218    
219            }
220            catch ( AuthorizationException e )
221            {
222                throw new ArchivaSecurityException( e.getMessage(), e);
223            }
224        }
225    
226        public SecuritySystem getSecuritySystem()
227        {
228            return securitySystem;
229        }
230    
231        public void setSecuritySystem( SecuritySystem securitySystem )
232        {
233            this.securitySystem = securitySystem;
234        }
235    
236        public RoleManager getRoleManager()
237        {
238            return roleManager;
239        }
240    
241        public void setRoleManager( RoleManager roleManager )
242        {
243            this.roleManager = roleManager;
244        }
245    }