/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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 org.guvnor.common.services.backend.migration; import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.guvnor.common.services.project.model.Project; import org.guvnor.common.services.project.security.ProjectAction; import org.guvnor.common.services.project.service.ProjectService; import org.guvnor.structure.organizationalunit.OrganizationalUnit; import org.guvnor.structure.organizationalunit.OrganizationalUnitService; import org.guvnor.structure.repositories.Repository; import org.guvnor.structure.repositories.RepositoryService; import org.guvnor.structure.security.OrganizationalUnitAction; import org.guvnor.structure.security.RepositoryAction; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.backend.events.AuthorizationPolicyDeployedEvent; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.Permission; import org.uberfire.security.authz.PermissionCollection; import org.uberfire.security.authz.PermissionManager; /** * In previous versions (before the 7 release), the only way to grant access to resources like * {@link OrganizationalUnit}, {@link Repository} and {@link Project} was to indicate which groups were able to * access a given instance. Those groups were stored as part of the instance persistent status. * * <p>As of 7 version, the authorization policy is based on permissions. That means is no longer required * to keep a list of groups per resource instance. What is required is to define proper permission entries into the * active {@link AuthorizationPolicy}</p> * * <p>This is a utility class which takes care of reading the groups declared for any of the above resource types and * creating the necessary permissions so that those resources are protected from user access.</p> * * <p>The migration procedure is carried out when an {@link AuthorizationPolicyDeployedEvent} is received, which means * the application is starting up and deploying the authorization policy for the first time.</p> */ @ApplicationScoped public class ACLMigrationTool { private OrganizationalUnitService organizationalUnitService; private RepositoryService repositoryService; private Instance<ProjectService<?>> projectServices; private PermissionManager permissionManager; private AuthorizationPolicyStorage authorizationPolicyStorage; private Map<String,Group> groupMap = new HashMap<>(); @Inject public ACLMigrationTool(OrganizationalUnitService organizationalUnitService, RepositoryService repositoryService, Instance<ProjectService<?>> projectServices, PermissionManager permissionManager, AuthorizationPolicyStorage authorizationPolicyStorage) { this.organizationalUnitService = organizationalUnitService; this.repositoryService = repositoryService; this.projectServices = projectServices; this.permissionManager = permissionManager; this.authorizationPolicyStorage = authorizationPolicyStorage; } public void onDeploy(@Observes AuthorizationPolicyDeployedEvent event) { AuthorizationPolicy policy = event.getPolicy(); migrateOrgUnits(policy); migrateRepositories(policy); authorizationPolicyStorage.savePolicy(policy); } private Group getGroup(String groupName) { Group group = groupMap.get(groupName); if (group == null) { group = new GroupImpl(groupName); groupMap.put(groupName, group); } return group; } public void migrateOrgUnits(AuthorizationPolicy policy) { Collection<OrganizationalUnit> itemList = organizationalUnitService.getAllOrganizationalUnits(); for (OrganizationalUnit item : itemList) { Permission p = permissionManager.createPermission(item, OrganizationalUnitAction.READ, true); for (String groupName : item.getGroups()) { Group group = getGroup(groupName); PermissionCollection pc = policy.getPermissions(group); pc.add(p); } } } public void migrateRepositories(AuthorizationPolicy policy) { Collection<Repository> itemList = repositoryService.getAllRepositories(); for (Repository item : itemList) { Permission p = permissionManager.createPermission(item, RepositoryAction.READ, true); for (String groupName : item.getGroups()) { Group group = getGroup(groupName); PermissionCollection pc = policy.getPermissions(group); pc.add(p); } migrateProjects(policy, item); } } public void migrateProjects(AuthorizationPolicy policy, Repository repository) { ProjectService projectService = getProjectService(); if (projectService != null) { Collection<Project> itemList = projectService.getAllProjects(repository, "master"); for (Project item : itemList) { Permission p = permissionManager.createPermission(item, ProjectAction.READ, true); for (String groupName : item.getGroups()) { Group group = getGroup(groupName); PermissionCollection pc = policy.getPermissions(group); pc.add(p); } } } } public ProjectService getProjectService() { return projectServices.get(); } }