org.apache.archiva.web.startup.SecuritySynchronization.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.archiva.web.startup.SecuritySynchronization.java

Source

package org.apache.archiva.web.startup;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import org.apache.archiva.common.ArchivaException;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.ConfigurationNames;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.role.RoleManagerException;
import org.apache.archiva.redback.system.check.EnvironmentCheck;
import org.apache.archiva.security.common.ArchivaRoleConstants;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.archiva.redback.rbac.RbacManagerException;
import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.components.registry.RegistryListener;
import org.apache.commons.lang.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * ConfigurationSynchronization
 */
@Service
public class SecuritySynchronization implements RegistryListener {
    private Logger log = LoggerFactory.getLogger(SecuritySynchronization.class);

    @Inject
    private RoleManager roleManager;

    @Inject
    @Named(value = "rbacManager#cached")
    private RBACManager rbacManager;

    private Map<String, EnvironmentCheck> checkers;

    @Inject
    private ArchivaConfiguration archivaConfiguration;

    @Inject
    private ApplicationContext applicationContext;

    @PostConstruct
    public void initialize() {
        checkers = getBeansOfType(EnvironmentCheck.class);
    }

    protected <T> Map<String, T> getBeansOfType(Class<T> clazz) {
        //TODO do some caching here !!!
        // olamy : with plexus we get only roleHint
        // as per convention we named spring bean role#hint remove role# if exists
        Map<String, T> springBeans = applicationContext.getBeansOfType(clazz);

        Map<String, T> beans = new HashMap<>(springBeans.size());

        for (Entry<String, T> entry : springBeans.entrySet()) {
            String key = StringUtils.substringAfterLast(entry.getKey(), "#");
            beans.put(key, entry.getValue());
        }
        return beans;
    }

    @Override
    public void afterConfigurationChange(org.apache.archiva.redback.components.registry.Registry registry,
            String propertyName, Object propertyValue) {
        if (ConfigurationNames.isManagedRepositories(propertyName) && propertyName.endsWith(".id")) {
            if (propertyValue != null) {
                syncRepoConfiguration((String) propertyValue);
            }
        }
    }

    @Override
    public void beforeConfigurationChange(org.apache.archiva.redback.components.registry.Registry registry,
            String propertyName, Object propertyValue) {
        /* do nothing */
    }

    private void synchConfiguration(List<ManagedRepositoryConfiguration> repos) {
        // NOTE: Remote Repositories do not have roles or security placed around them.

        for (ManagedRepositoryConfiguration repoConfig : repos) {
            syncRepoConfiguration(repoConfig.getId());
        }
    }

    private void syncRepoConfiguration(String id) {
        // manage roles for repositories
        try {
            if (!roleManager.templatedRoleExists(ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, id)) {
                roleManager.createTemplatedRole(ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, id);
            } else {
                roleManager.verifyTemplatedRole(ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, id);
            }

            if (!roleManager.templatedRoleExists(ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, id)) {
                roleManager.createTemplatedRole(ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, id);
            } else {
                roleManager.verifyTemplatedRole(ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, id);
            }
        } catch (RoleManagerException e) {
            // Log error.
            log.error("Unable to create roles for configured repositories: " + e.getMessage(), e);
        }
    }

    public void startup() throws ArchivaException {
        executeEnvironmentChecks();

        synchConfiguration(archivaConfiguration.getConfiguration().getManagedRepositories());
        archivaConfiguration.addChangeListener(this);

        if (archivaConfiguration.isDefaulted()) {
            assignRepositoryObserverToGuestUser(archivaConfiguration.getConfiguration().getManagedRepositories());
        }
    }

    private void executeEnvironmentChecks() throws ArchivaException {
        if ((checkers == null) || CollectionUtils.isEmpty(checkers.values())) {
            throw new ArchivaException("Unable to initialize the Redback Security Environment, "
                    + "no Environment Check components found.");
        }

        StopWatch stopWatch = new StopWatch();
        stopWatch.reset();
        stopWatch.start();

        List<String> violations = new ArrayList<>();

        for (Entry<String, EnvironmentCheck> entry : checkers.entrySet()) {
            EnvironmentCheck check = entry.getValue();
            List<String> v = new ArrayList<>();
            check.validateEnvironment(v);
            log.info("Environment Check: {} -> {} violation(s)", entry.getKey(), v.size());
            for (String s : v) {
                violations.add("[" + entry.getKey() + "] " + s);
            }
        }

        if (CollectionUtils.isNotEmpty(violations)) {
            StringBuilder msg = new StringBuilder();
            msg.append("EnvironmentCheck Failure.\n");
            msg.append("======================================================================\n");
            msg.append(" ENVIRONMENT FAILURE !! \n");
            msg.append("\n");

            for (String violation : violations) {
                msg.append(violation).append("\n");
            }

            msg.append("\n");
            msg.append("======================================================================");
            log.error(msg.toString());

            throw new ArchivaException("Unable to initialize Redback Security Environment, [" + violations.size()
                    + "] violation(s) encountered, See log for details.");
        }

        stopWatch.stop();
        log.info("time to execute all EnvironmentCheck: {} ms", stopWatch.getTime());
    }

    private void assignRepositoryObserverToGuestUser(List<ManagedRepositoryConfiguration> repos) {
        for (ManagedRepositoryConfiguration repoConfig : repos) {
            String repoId = repoConfig.getId();

            String principal = UserManager.GUEST_USERNAME;

            try {
                UserAssignment ua;

                if (rbacManager.userAssignmentExists(principal)) {
                    ua = rbacManager.getUserAssignment(principal);
                } else {
                    ua = rbacManager.createUserAssignment(principal);
                }

                ua.addRoleName(ArchivaRoleConstants.toRepositoryObserverRoleName(repoId));
                rbacManager.saveUserAssignment(ua);
            } catch (RbacManagerException e) {
                log.warn("Unable to add role [{}] to {} user.",
                        ArchivaRoleConstants.toRepositoryObserverRoleName(repoId), principal, e);
            }
        }
    }
}