com.vmware.identity.openidconnect.server.UserInfoRetriever.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.identity.openidconnect.server.UserInfoRetriever.java

Source

/*
 *  Copyright (c) 2012-2015 VMware, Inc.  All Rights Reserved.
 *
 *  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.vmware.identity.openidconnect.server;

import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.Validate;

import com.vmware.identity.idm.Attribute;
import com.vmware.identity.idm.AttributeValuePair;
import com.vmware.identity.idm.DomainType;
import com.vmware.identity.idm.IIdentityStoreData;
import com.vmware.identity.idm.InvalidPrincipalException;
import com.vmware.identity.idm.KnownSamlAttributes;
import com.vmware.identity.idm.client.CasIdmClient;
import com.vmware.identity.openidconnect.common.ErrorObject;
import com.vmware.identity.openidconnect.common.Scope;
import com.vmware.identity.openidconnect.common.ScopeValue;

/**
 * @author Yehia Zayour
 */
public class UserInfoRetriever {
    private final CasIdmClient idmClient;

    public UserInfoRetriever(CasIdmClient idmClient) {
        Validate.notNull(idmClient, "idmClient");
        this.idmClient = idmClient;
    }

    public UserInfo retrieveUserInfo(User user, Scope scope, Set<ResourceServerInfo> resourceServerInfos)
            throws ServerException {
        Validate.notNull(user, "user");
        Validate.notNull(scope, "scope");
        Validate.notNull(resourceServerInfos, "resourceServerInfos");

        if (!isEnabled(user)) {
            throw new ServerException(ErrorObject.accessDenied("user has been disabled or deleted"));
        }

        String givenName = null;
        String familyName = null;
        if (user instanceof PersonUser) {
            com.vmware.identity.idm.PersonUser idmPersonUser;
            try {
                idmPersonUser = this.idmClient.findPersonUser(user.getTenant(), user.getPrincipalId());
            } catch (Exception e) {
                throw new ServerException(ErrorObject.serverError("idm error while retrieving person user"), e);
            }
            if (idmPersonUser == null) {
                throw new ServerException(ErrorObject.invalidRequest("person user with specified id not found"));
            }
            givenName = idmPersonUser.getDetail().getFirstName();
            familyName = idmPersonUser.getDetail().getLastName();
        }

        List<String> groupMembership = null;
        if (scope.contains(ScopeValue.ID_TOKEN_GROUPS) || scope.contains(ScopeValue.ID_TOKEN_GROUPS_FILTERED)
                || scope.contains(ScopeValue.ACCESS_TOKEN_GROUPS)
                || scope.contains(ScopeValue.ACCESS_TOKEN_GROUPS_FILTERED)
                || scope.contains(ScopeValue.RESOURCE_SERVER_ADMIN_SERVER)) {
            groupMembership = computeGroupMembership(user);
        }

        String adminServerRole = null;
        if (scope.contains(ScopeValue.RESOURCE_SERVER_ADMIN_SERVER)) {
            adminServerRole = computeAdminServerRole(user, groupMembership);
        }

        boolean filteredGroupsRequested = scope.contains(ScopeValue.ID_TOKEN_GROUPS_FILTERED)
                || scope.contains(ScopeValue.ACCESS_TOKEN_GROUPS_FILTERED);

        boolean shouldComputeFilteredGroups = false;
        if (filteredGroupsRequested && !resourceServerInfos.isEmpty()) {
            boolean emptyFilterFound = false;
            for (ResourceServerInfo rsInfo : resourceServerInfos) {
                if (rsInfo.getGroupFilter().isEmpty()) {
                    emptyFilterFound = true;
                    break;
                }
            }
            if (!emptyFilterFound) {
                shouldComputeFilteredGroups = true;
            }
        }

        Set<String> groupMembershipFiltered = null;
        if (shouldComputeFilteredGroups) {
            groupMembershipFiltered = computeGroupMembershipFiltered(groupMembership, resourceServerInfos);
        }

        return new UserInfo(groupMembership, groupMembershipFiltered, adminServerRole, givenName, familyName);
    }

    public boolean isMemberOfGroup(User user, String group) throws ServerException {
        Validate.notNull(user, "user");
        Validate.notEmpty(group, "group");
        try {
            return this.idmClient.isMemberOfSystemGroup(user.getTenant(), user.getPrincipalId(), group);
        } catch (Exception e) {
            throw new ServerException(ErrorObject.serverError("idm error while checking is member of system group"),
                    e);
        }
    }

    private boolean isEnabled(User user) throws ServerException {
        boolean enabled;
        try {
            enabled = this.idmClient.isActive(user.getTenant(), user.getPrincipalId());
        } catch (InvalidPrincipalException e) {
            enabled = false;
        } catch (Exception e) {
            throw new ServerException(ErrorObject.serverError("idm error while checking isActive status"), e);
        }
        return enabled;
    }

    private Set<String> computeGroupMembershipFiltered(List<String> groupMembership,
            Set<ResourceServerInfo> resourceServerInfos) {
        // 1. result = {union of all filters}
        Set<String> result = new HashSet<String>();
        for (ResourceServerInfo rsInfo : resourceServerInfos) {
            assert !rsInfo.getGroupFilter().isEmpty();
            Set<String> groupFilterLowerCase = toLowerCase(rsInfo.getGroupFilter());
            result.addAll(groupFilterLowerCase);
        }

        // 2. result = intersection of {union of all filters} with groupMembership
        Set<String> groupMembershipLowerCase = toLowerCase(groupMembership);
        result.retainAll(groupMembershipLowerCase);
        return result;
    }

    private List<String> computeGroupMembership(User user) throws ServerException {
        Collection<AttributeValuePair> attributeValuePairs;
        try {
            attributeValuePairs = this.idmClient.getAttributeValues(user.getTenant(), user.getPrincipalId(),
                    Collections.singleton(new Attribute(KnownSamlAttributes.ATTRIBUTE_USER_GROUPS)));
        } catch (Exception e) {
            throw new ServerException(ErrorObject.serverError("idm error while retrieving group membership"), e);
        }
        assert attributeValuePairs != null && attributeValuePairs.size() == 1;
        AttributeValuePair attributeValuePair = attributeValuePairs.iterator().next();
        return attributeValuePair.getValues();
    }

    private String computeAdminServerRole(User user, List<String> groupMembership) throws ServerException {
        String systemDomainName = getSystemDomainName(user);
        String groupNamePrefix = systemDomainName.toLowerCase() + "\\";
        Set<String> groupMembershipLowerCase = toLowerCase(groupMembership);

        String role;
        if (groupMembershipLowerCase.contains(groupNamePrefix + "administrators")) {
            role = "Administrator";
        } else if (groupMembershipLowerCase.contains(groupNamePrefix + "systemconfiguration.administrators")) {
            role = "ConfigurationUser";
        } else if (groupMembershipLowerCase.contains(groupNamePrefix + "users")) {
            role = "RegularUser";
        } else {
            role = "GuestUser";
        }
        return role;
    }

    private String getSystemDomainName(User user) throws ServerException {
        Collection<IIdentityStoreData> identityStores;
        try {
            identityStores = this.idmClient.getProviders(user.getTenant(), EnumSet.of(DomainType.SYSTEM_DOMAIN));
        } catch (Exception e) {
            throw new ServerException(ErrorObject.serverError("idm error while retrieving system domain"), e);
        }
        assert identityStores != null && identityStores.size() == 1;
        IIdentityStoreData identityStore = identityStores.iterator().next();
        return identityStore.getName();
    }

    private static Set<String> toLowerCase(Collection<String> collection) {
        Set<String> result = new HashSet<String>();
        for (String element : collection) {
            result.add(element.toLowerCase());
        }
        return result;
    }
}