org.opentestsystem.shared.security.service.RoleSpecificPermissionsService.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.shared.security.service.RoleSpecificPermissionsService.java

Source

/*******************************************************************************
 * Educational Online Test Delivery System 
 * Copyright (c) 2014 American Institutes for Research
 *   
 * Distributed under the AIR Open Source License, Version 1.0 
 * See accompanying file AIR-License-1_0.txt or at
 * https://bitbucket.org/sbacoss/eotds/wiki/AIR_Open_Source_License
 ******************************************************************************/
package org.opentestsystem.shared.security.service;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.opentestsystem.shared.progman.client.domain.Tenant;
import org.opentestsystem.shared.security.domain.RoleSpecificPermisionsResolver;
import org.opentestsystem.shared.security.domain.SbacEntity;
import org.opentestsystem.shared.security.domain.SbacPermission;
import org.opentestsystem.shared.security.domain.SbacRole;
import org.opentestsystem.shared.security.domain.permission.RoleToPermissionMapping;
import org.opentestsystem.shared.security.integration.PermissionClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

/**
 * Impl of the RolesAndPermissionsService allows applications to override the base impl of RolesAndPermissionService,
 * eliminating the hard dependency on the Permission Component at runtime.<br>
 * When properly configured, a component can implement an interface @see org.opentestsystem.shared.security.domain.RoleSpecificPermisionsResolver,
 * which will enable it to specify Roles to look for, and permissions to bind to it
 * <br><br>
 * In order to use this RoleSpecificPermissionService, a component needs to:
 * <li> add a new profile to spring.profiles.active "special.role.required"
 * <li> wire a spring bean that implements the RoleSpecificPermisionsResolver interface (see ProgmanPermissionsResolver in the progman component for an example)
 *
 */
@Service
@Profile("special.role.required")
public class RoleSpecificPermissionsService extends AbsractRolesAndPermissionsService
        implements RolesAndPermissionsService {

    @Value("${component.name:}")
    protected String componentName;

    @Autowired(required = true)
    private RoleSpecificPermisionsResolver permissionResolver;
    private Map<String, RoleToPermissionMapping> roleMapping;

    @Override
    protected Multimap<String, SbacRole> buildRolesFromParsedStrings(
            final Map<String, RoleToPermissionMapping> inRoleToPermissionMappings,
            final List<String[]> inRoleStrings) {
        Multimap<String, SbacRole> retRoles = ArrayListMultimap.create();
        Multimap<String, SbacPermission> roleNamesToLookFor = permissionResolver.getRoleBindings(componentName);
        if (inRoleStrings != null && roleNamesToLookFor != null) {
            for (String[] roleAttributes : inRoleStrings) {
                SbacRole role = extractRole(roleAttributes);
                if (roleNamesToLookFor.keySet().contains(role.getRoleName())) {
                    role.setIsApplicableToTenant(true);
                    role.setPermissions(roleNamesToLookFor.get(role.getRoleName()));
                    retRoles.put(role.getRoleName(), role);
                }
            }
        }
        return retRoles;
    }

    @Override
    public Collection<String> getKnownRoleNames() {
        //resolve the role name locally (no permission client.)
        return permissionResolver.getRoleBindings(componentName).keySet();
    }

    @Override
    public Map<String, RoleToPermissionMapping> getKnownRoles() {
        // resolve the role mappings locally (no permission client)
        return getRoleMapping();
    }

    //lazy init
    private Map<String, RoleToPermissionMapping> getRoleMapping() {
        if (roleMapping == null) {
            Map<String, RoleToPermissionMapping> map = new HashMap<String, RoleToPermissionMapping>();
            Multimap<String, SbacPermission> resolvedRoles = permissionResolver.getRoleBindings(componentName);
            for (String sbacRoleName : resolvedRoles.keySet()) {
                RoleToPermissionMapping mapping = new RoleToPermissionMapping(sbacRoleName,
                        resolvedRoles.get(sbacRoleName), true);
                map.put(sbacRoleName, mapping);
            }
            roleMapping = map;
        }
        return roleMapping;
    }

    @Override
    protected String getComponentName() {
        return componentName;
    }

    @Override
    protected List<Tenant> getApplicableTenants(final HashSet<SbacEntity> inNewHashSet) {
        return null;
    }

    @Override
    public void setPermissionClient(final PermissionClient inPermissionClient) {
        //no need, this impl is permission client free
    }
}