/* * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.security.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import com.evolveum.midpoint.common.ActivationComputer; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.security.api.Authorization; import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.security.api.UserProfileService; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author semancik */ @Component public class UserProfileServiceMock implements UserProfileService, UserDetailsService { private static final Trace LOGGER = TraceManager.getTrace(UserProfileServiceMock.class); @Autowired(required = true) private transient RepositoryService repositoryService; @Autowired(required = true) private ActivationComputer activationComputer; @Autowired(required = true) private Clock clock; @Autowired(required = true) private PrismContext prismContext; @Override public MidPointPrincipal getPrincipal(String username) throws ObjectNotFoundException { OperationResult result = new OperationResult(OPERATION_GET_PRINCIPAL); PrismObject<UserType> user = null; try { user = findByUsername(username, result); } catch (ObjectNotFoundException ex) { LOGGER.trace("Couldn't find user with name '{}', reason: {}.", new Object[]{username, ex.getMessage(), ex}); throw ex; } catch (Exception ex) { LOGGER.warn("Error getting user with name '{}', reason: {}.", new Object[]{username, ex.getMessage(), ex}); throw new SystemException(ex.getMessage(), ex); } return createPrincipal(user, result); } @Override public MidPointPrincipal getPrincipal(PrismObject<UserType> user) { OperationResult result = new OperationResult(OPERATION_GET_PRINCIPAL); return createPrincipal(user, result); } private MidPointPrincipal createPrincipal(PrismObject<UserType> user, OperationResult result) { if (user == null) { return null; } PrismObject<SystemConfigurationType> systemConfiguration = null; try { systemConfiguration = repositoryService.getObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), null, result); } catch (ObjectNotFoundException | SchemaException e) { LOGGER.warn("No system configuration: {}", e.getMessage(), e); } MidPointPrincipal principal = new MidPointPrincipal(user.asObjectable()); initializePrincipalFromAssignments(principal, systemConfiguration); return principal; } @Override public void updateUser(MidPointPrincipal principal) { OperationResult result = new OperationResult(OPERATION_UPDATE_USER); try { save(principal, result); } catch (Exception ex) { LOGGER.warn("Couldn't save user '{}, ({})', reason: {}.", new Object[]{principal.getFullName(), principal.getOid(), ex.getMessage()}); } } private PrismObject<UserType> findByUsername(String username, OperationResult result) throws SchemaException, ObjectNotFoundException { PolyString usernamePoly = new PolyString(username); ObjectQuery query = ObjectQueryUtil.createNormNameQuery(usernamePoly, prismContext); LOGGER.trace("Looking for user, query:\n" + query.debugDump()); List<PrismObject<UserType>> list = repositoryService.searchObjects(UserType.class, query, null, result); LOGGER.trace("Users found: {}.", (list != null ? list.size() : 0)); if (list == null || list.size() != 1) { return null; } return list.get(0); } private void initializePrincipalFromAssignments(MidPointPrincipal principal, PrismObject<SystemConfigurationType> systemConfiguration) { OperationResult result = new OperationResult(UserProfileServiceMock.class.getName() + ".addAuthorizations"); principal.setApplicableSecurityPolicy(locateSecurityPolicy(principal, systemConfiguration, result)); if (systemConfiguration != null) { principal.setAdminGuiConfiguration(systemConfiguration.asObjectable().getAdminGuiConfiguration()); } AuthorizationType authorizationType = new AuthorizationType(); authorizationType.getAction().add("FAKE"); principal.getAuthorities().add(new Authorization(authorizationType)); ActivationType activation = principal.getUser().getActivation(); if (activation != null) { activationComputer.computeEffective(principal.getUser().getLifecycleState(), activation); } } private SecurityPolicyType locateSecurityPolicy(MidPointPrincipal principal, PrismObject<SystemConfigurationType> systemConfiguration, OperationResult result) { if (systemConfiguration == null) { return null; } ObjectReferenceType globalSecurityPolicyRef = systemConfiguration.asObjectable().getGlobalSecurityPolicyRef(); if (globalSecurityPolicyRef == null) { return null; } try { PrismObject<SecurityPolicyType> policy = repositoryService.getObject(SecurityPolicyType.class, globalSecurityPolicyRef.getOid(), null, result); return policy.asObjectable(); } catch (ObjectNotFoundException | SchemaException e) { LOGGER.error(e.getMessage(), e); return null; } } private MidPointPrincipal save(MidPointPrincipal person, OperationResult result) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { UserType oldUserType = getUserByOid(person.getOid(), result); PrismObject<UserType> oldUser = oldUserType.asPrismObject(); PrismObject<UserType> newUser = person.getUser().asPrismObject(); ObjectDelta<UserType> delta = oldUser.diff(newUser); repositoryService.modifyObject(UserType.class, delta.getOid(), delta.getModifications(), new OperationResult(OPERATION_UPDATE_USER)); return person; } private UserType getUserByOid(String oid, OperationResult result) throws ObjectNotFoundException, SchemaException { ObjectType object = repositoryService.getObject(UserType.class, oid, null, result).asObjectable(); if (object != null && (object instanceof UserType)) { return (UserType) object; } return null; } @Override public <F extends FocusType, O extends ObjectType> PrismObject<F> resolveOwner(PrismObject<O> object) { if (object == null || object.getOid() == null) { return null; } PrismObject<F> owner = null; if (object.canRepresent(ShadowType.class)) { owner = repositoryService.searchShadowOwner(object.getOid(), null, new OperationResult(UserProfileServiceMock.class+".resolveOwner")); } else if (object.canRepresent(AbstractRoleType.class)) { ObjectReferenceType ownerRef = ((AbstractRoleType)(object.asObjectable())).getOwnerRef(); if (ownerRef != null && ownerRef.getOid() != null && ownerRef.getType() != null) { OperationResult result = new OperationResult(UserProfileService.class.getName() + ".resolveOwner"); try { owner = (PrismObject<F>) repositoryService.getObject(ObjectTypes.getObjectTypeFromTypeQName(ownerRef.getType()).getClassDefinition(), ownerRef.getOid(), null, result); } catch (ObjectNotFoundException | SchemaException e) { LOGGER.warn("Cannot resolve owner of {}: {}", object, e.getMessage(), e); } } } if (owner == null) { return null; } return owner; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO Auto-generated method stub try { return getPrincipal(username); } catch (ObjectNotFoundException e) { throw new UsernameNotFoundException(e.getMessage(), e); } } }