All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.finra.herd.service.impl.UserNamespaceAuthorizationServiceImpl Maven / Gradle / Ivy

Go to download

This project contains the business service code. This is a classic service tier where business logic is defined along with it's associated transaction management configuration.

There is a newer version: 0.160.0
Show newest version
/*
* Copyright 2015 herd contributors
*
* 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.finra.herd.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import org.finra.herd.dao.UserNamespaceAuthorizationDao;
import org.finra.herd.dao.config.DaoSpringModuleConfig;
import org.finra.herd.model.AlreadyExistsException;
import org.finra.herd.model.ObjectNotFoundException;
import org.finra.herd.model.annotation.NamespacePermission;
import org.finra.herd.model.annotation.PublishNotificationMessages;
import org.finra.herd.model.api.xml.NamespacePermissionEnum;
import org.finra.herd.model.api.xml.UserAuthorizations;
import org.finra.herd.model.api.xml.UserNamespaceAuthorization;
import org.finra.herd.model.api.xml.UserNamespaceAuthorizationCreateRequest;
import org.finra.herd.model.api.xml.UserNamespaceAuthorizationKey;
import org.finra.herd.model.api.xml.UserNamespaceAuthorizationUpdateRequest;
import org.finra.herd.model.api.xml.UserNamespaceAuthorizations;
import org.finra.herd.model.jpa.NamespaceEntity;
import org.finra.herd.model.jpa.UserNamespaceAuthorizationEntity;
import org.finra.herd.service.CurrentUserService;
import org.finra.herd.service.MessageNotificationEventService;
import org.finra.herd.service.NotificationEventService;
import org.finra.herd.service.UserNamespaceAuthorizationService;
import org.finra.herd.service.helper.AlternateKeyHelper;
import org.finra.herd.service.helper.NamespaceDaoHelper;
import org.finra.herd.service.helper.UserNamespaceAuthorizationHelper;

/**
 * The user namespace authorization service implementation.
 */
@Service
@Transactional(value = DaoSpringModuleConfig.HERD_TRANSACTION_MANAGER_BEAN_NAME)
public class UserNamespaceAuthorizationServiceImpl implements UserNamespaceAuthorizationService
{
    @Autowired
    private AlternateKeyHelper alternateKeyHelper;

    @Autowired
    private CurrentUserService currentUserService;

    @Autowired
    private NamespaceDaoHelper namespaceDaoHelper;

    @Autowired
    private UserNamespaceAuthorizationDao userNamespaceAuthorizationDao;

    @Autowired
    private UserNamespaceAuthorizationHelper userNamespaceAuthorizationHelper;

    @Autowired
    private MessageNotificationEventService messageNotificationEventService;

    @PublishNotificationMessages
    @NamespacePermission(fields = "#request?.userNamespaceAuthorizationKey?.namespace", permissions = NamespacePermissionEnum.GRANT)
    @Override
    public UserNamespaceAuthorization createUserNamespaceAuthorization(UserNamespaceAuthorizationCreateRequest request)
    {
        // Validate and trim the request parameters.
        validateUserNamespaceAuthorizationCreateRequest(request);

        // Get the user namespace authorization key.
        UserNamespaceAuthorizationKey key = request.getUserNamespaceAuthorizationKey();

        // Ensure a user namespace authorization with the specified name doesn't already exist for the specified namespace.
        UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity = userNamespaceAuthorizationDao.getUserNamespaceAuthorizationByKey(key);
        if (userNamespaceAuthorizationEntity != null)
        {
            throw new AlreadyExistsException(String
                .format("Unable to create user namespace authorization with user id \"%s\" and namespace \"%s\" because it already exists.", key.getUserId(),
                    key.getNamespace()));
        }

        // Retrieve and ensure that namespace exists with the specified user namespace authorization namespace code.
        NamespaceEntity namespaceEntity = namespaceDaoHelper.getNamespaceEntity(key.getNamespace());

        // Create and persist a new user namespace authorization entity from the request information.
        userNamespaceAuthorizationEntity = createUserNamespaceAuthorizationEntity(key.getUserId(), namespaceEntity, request.getNamespacePermissions());

        // Create a user namespace authorization change notification to be sent on create user namespace authorization event.
        messageNotificationEventService.processUserNamespaceAuthorizationChangeNotificationEvent(key);

        // Create and return the user namespace authorization object from the persisted entity.
        return createUserNamespaceAuthorizationFromEntity(userNamespaceAuthorizationEntity);
    }

    @PublishNotificationMessages
    @NamespacePermission(fields = "#key?.namespace", permissions = NamespacePermissionEnum.GRANT)
    @Override
    public UserNamespaceAuthorization updateUserNamespaceAuthorization(UserNamespaceAuthorizationKey key, UserNamespaceAuthorizationUpdateRequest request)
    {
        // Validate and trim the key.
        validateUserNamespaceAuthorizationKey(key);

        // Validate and trim the request parameters.
        validateUserNamespaceAuthorizationUpdateRequest(request);

        // Retrieve and ensure that a user namespace authorization exists with the specified key.
        UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity = getUserNamespaceAuthorizationEntity(key);

        // Get the current user
        UserAuthorizations userAuthorizations = currentUserService.getCurrentUser();

        // If the current user id is equal to the user id in the namespace authorization key
        // and the user namespace authorization entity contains the grant permission
        if (userAuthorizations.getUserId().equalsIgnoreCase(key.getUserId()) && userNamespaceAuthorizationEntity.getGrantPermission())
        {
            // Assert that the request contains the grant namespace permission
            Assert.isTrue(request.getNamespacePermissions().contains(NamespacePermissionEnum.GRANT),
                "Users are not allowed to remove their own GRANT namespace permission." +
                    " Please include the GRANT namespace permission in this request, or have another user remove the GRANT permission.");
        }

        // Update the permissions.
        updateNamespacePermissions(userNamespaceAuthorizationEntity, request.getNamespacePermissions());
        userNamespaceAuthorizationDao.saveAndRefresh(userNamespaceAuthorizationEntity);

        // Create a user namespace authorization change notification to be sent on update user namespace authorization event.
        messageNotificationEventService.processUserNamespaceAuthorizationChangeNotificationEvent(key);

        // Create and return the user namespace authorization object from the updated entity.
        return createUserNamespaceAuthorizationFromEntity(userNamespaceAuthorizationEntity);
    }

    @NamespacePermission(fields = "#key?.namespace", permissions = NamespacePermissionEnum.READ)
    @Override
    public UserNamespaceAuthorization getUserNamespaceAuthorization(UserNamespaceAuthorizationKey key)
    {
        // Validate and trim the key.
        validateUserNamespaceAuthorizationKey(key);

        // Retrieve and ensure that a user namespace authorization exists with the specified key.
        UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity = getUserNamespaceAuthorizationEntity(key);

        // Create and return the user namespace authorization object from the persisted entity.
        return createUserNamespaceAuthorizationFromEntity(userNamespaceAuthorizationEntity);
    }

    @PublishNotificationMessages
    @NamespacePermission(fields = "#key?.namespace", permissions = NamespacePermissionEnum.GRANT)
    @Override
    public UserNamespaceAuthorization deleteUserNamespaceAuthorization(UserNamespaceAuthorizationKey key)
    {
        // Validate and trim the key.
        validateUserNamespaceAuthorizationKey(key);

        // Retrieve and ensure that a user namespace authorization exists with the specified key.
        UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity = getUserNamespaceAuthorizationEntity(key);

        // Delete the business object definition.
        userNamespaceAuthorizationDao.delete(userNamespaceAuthorizationEntity);

        // Create a user namespace authorization change notification to be sent on delete user namespace authorization event.
        messageNotificationEventService.processUserNamespaceAuthorizationChangeNotificationEvent(key);

        // Create and return the user namespace authorization object from the deleted entity.
        return createUserNamespaceAuthorizationFromEntity(userNamespaceAuthorizationEntity);
    }

    @Override
    public UserNamespaceAuthorizations getUserNamespaceAuthorizationsByUserId(String userId)
    {
        // Validate and trim the user id.
        Assert.hasText(userId, "A user id must be specified.");
        String userIdLocal = userId.trim();

        // Retrieve and return a list of user namespace authorization entities for the specified user id.
        List userNamespaceAuthorizationEntities =
            userNamespaceAuthorizationDao.getUserNamespaceAuthorizationsByUserId(userIdLocal);

        // Create and populate the user namespace authorizations object from the returned entities.
        UserNamespaceAuthorizations userNamespaceAuthorizations = new UserNamespaceAuthorizations();
        userNamespaceAuthorizations.getUserNamespaceAuthorizations().addAll(createUserNamespaceAuthorizationsFromEntities(userNamespaceAuthorizationEntities));

        return userNamespaceAuthorizations;
    }

    @NamespacePermission(fields = "#namespace", permissions = NamespacePermissionEnum.READ)
    @Override
    public UserNamespaceAuthorizations getUserNamespaceAuthorizationsByNamespace(String namespace)
    {
        // Validate and trim the namespace code.
        Assert.hasText(namespace, "A namespace must be specified.");
        String namespaceLocal = namespace.trim();

        // Validate that specified namespace exists.
        namespaceDaoHelper.getNamespaceEntity(namespaceLocal);

        // Retrieve and return a list of user namespace authorization entities for the specified namespace.
        List userNamespaceAuthorizationEntities =
            userNamespaceAuthorizationDao.getUserNamespaceAuthorizationsByNamespace(namespaceLocal);

        // Create and populate the user namespace authorizations object from the returned entities.
        UserNamespaceAuthorizations userNamespaceAuthorizations = new UserNamespaceAuthorizations();
        userNamespaceAuthorizations.getUserNamespaceAuthorizations().addAll(createUserNamespaceAuthorizationsFromEntities(userNamespaceAuthorizationEntities));

        return userNamespaceAuthorizations;
    }

    /**
     * Validates the user namespace authorization create request. This method also trims the request parameters.
     *
     * @param request the user namespace authorization create request
     */
    private void validateUserNamespaceAuthorizationCreateRequest(UserNamespaceAuthorizationCreateRequest request)
    {
        Assert.notNull(request, "A user namespace authorization create request must be specified.");

        validateUserNamespaceAuthorizationKey(request.getUserNamespaceAuthorizationKey());
        validateNamespacePermissions(request.getNamespacePermissions());
    }

    /**
     * Validates the user namespace authorization update request. This method also trims the request parameters.
     *
     * @param request the user namespace authorization update request
     */
    private void validateUserNamespaceAuthorizationUpdateRequest(UserNamespaceAuthorizationUpdateRequest request)
    {
        Assert.notNull(request, "A user namespace authorization update request must be specified.");

        validateNamespacePermissions(request.getNamespacePermissions());
    }

    /**
     * Validates the user namespace authorization key. This method also trims the key parameters.
     *
     * @param key the user namespace authorization key
     *
     * @throws IllegalArgumentException if any validation errors were found
     */
    public void validateUserNamespaceAuthorizationKey(UserNamespaceAuthorizationKey key) throws IllegalArgumentException
    {
        Assert.notNull(key, "A user namespace authorization key must be specified.");
        key.setNamespace(alternateKeyHelper.validateStringParameter("namespace", key.getNamespace()));
        key.setUserId(alternateKeyHelper.validateStringParameter("user id", key.getUserId()));
    }

    /**
     * Validates a list of namespace permissions.
     *
     * @param namespacePermissions the list of namespace permissions
     *
     * @throws IllegalArgumentException if any validation errors were found
     */
    public void validateNamespacePermissions(List namespacePermissions) throws IllegalArgumentException
    {
        Assert.isTrue(!CollectionUtils.isEmpty(namespacePermissions), "Namespace permissions must be specified.");

        // Ensure permission isn't a duplicate by using a hash set with uppercase permission values for case insensitivity.
        Set validatedNamespacePermissions = new HashSet<>();

        // Validate the permissions.
        for (NamespacePermissionEnum namespacePermission : namespacePermissions)
        {
            // Fail if duplicate permission value is detected.
            if (validatedNamespacePermissions.contains(namespacePermission))
            {
                throw new IllegalArgumentException(String.format("Duplicate namespace permission \"%s\" is found.", namespacePermission.value()));
            }

            validatedNamespacePermissions.add(namespacePermission);
        }
    }

    /**
     * Creates and persists a new user namespace authorization entity.
     *
     * @param userId the user id
     * @param namespaceEntity the namespace entity
     * @param namespacePermissions the list of namespace permissions
     *
     * @return the newly created user namespace authorization entity
     */
    private UserNamespaceAuthorizationEntity createUserNamespaceAuthorizationEntity(String userId, NamespaceEntity namespaceEntity,
        List namespacePermissions)
    {
        UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity = new UserNamespaceAuthorizationEntity();

        userNamespaceAuthorizationEntity.setUserId(userId);
        userNamespaceAuthorizationEntity.setNamespace(namespaceEntity);
        updateNamespacePermissions(userNamespaceAuthorizationEntity, namespacePermissions);

        return userNamespaceAuthorizationDao.saveAndRefresh(userNamespaceAuthorizationEntity);
    }

    /**
     * Sets relative flags on the user namespace authorization entity as per specified list of namespace permissions.
     *
     * @param userNamespaceAuthorizationEntity the user namespace authorization entity
     * @param namespacePermissions the list of namespace permissions
     */
    private void updateNamespacePermissions(UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity,
        List namespacePermissions)
    {
        userNamespaceAuthorizationEntity.setReadPermission(namespacePermissions.contains(NamespacePermissionEnum.READ));
        userNamespaceAuthorizationEntity.setWritePermission(namespacePermissions.contains(NamespacePermissionEnum.WRITE));
        userNamespaceAuthorizationEntity.setExecutePermission(namespacePermissions.contains(NamespacePermissionEnum.EXECUTE));
        userNamespaceAuthorizationEntity.setGrantPermission(namespacePermissions.contains(NamespacePermissionEnum.GRANT));
        userNamespaceAuthorizationEntity.setWriteDescriptiveContentPermission(namespacePermissions.contains(NamespacePermissionEnum.WRITE_DESCRIPTIVE_CONTENT));
        userNamespaceAuthorizationEntity.setWriteAttributePermission(namespacePermissions.contains(NamespacePermissionEnum.WRITE_ATTRIBUTE));
    }

    /**
     * Creates a list of user namespace authorizations from the list of persisted entities.
     *
     * @param userNamespaceAuthorizationEntities the list of user namespace authorization entities
     *
     * @return the list of user namespace authorizations
     */
    private List createUserNamespaceAuthorizationsFromEntities(
        List userNamespaceAuthorizationEntities)
    {
        List userNamespaceAuthorizations = new ArrayList<>();

        for (UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity : userNamespaceAuthorizationEntities)
        {
            userNamespaceAuthorizations.add(createUserNamespaceAuthorizationFromEntity(userNamespaceAuthorizationEntity));
        }

        return userNamespaceAuthorizations;
    }

    /**
     * Creates the user namespace authorization from the persisted entity.
     *
     * @param userNamespaceAuthorizationEntity the user namespace authorization entity
     *
     * @return the user namespace authorization
     */
    private UserNamespaceAuthorization createUserNamespaceAuthorizationFromEntity(UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity)
    {
        UserNamespaceAuthorization userNamespaceAuthorization = new UserNamespaceAuthorization();

        userNamespaceAuthorization.setId(userNamespaceAuthorizationEntity.getId());

        UserNamespaceAuthorizationKey userNamespaceAuthorizationKey = new UserNamespaceAuthorizationKey();
        userNamespaceAuthorization.setUserNamespaceAuthorizationKey(userNamespaceAuthorizationKey);
        userNamespaceAuthorizationKey.setUserId(userNamespaceAuthorizationEntity.getUserId());
        userNamespaceAuthorizationKey.setNamespace(userNamespaceAuthorizationEntity.getNamespace().getCode());

        userNamespaceAuthorization.setNamespacePermissions(userNamespaceAuthorizationHelper.getNamespacePermissions(userNamespaceAuthorizationEntity));

        return userNamespaceAuthorization;
    }

    /**
     * Gets a storage entity based on the storage name and makes sure that it exists.
     *
     * @param key the user namespace authorization key (case insensitive)
     *
     * @return the user namespace authorization entity
     * @throws org.finra.herd.model.ObjectNotFoundException if the user namespace authorization entity doesn't exist
     */
    private UserNamespaceAuthorizationEntity getUserNamespaceAuthorizationEntity(UserNamespaceAuthorizationKey key) throws ObjectNotFoundException
    {
        UserNamespaceAuthorizationEntity userNamespaceAuthorizationEntity = userNamespaceAuthorizationDao.getUserNamespaceAuthorizationByKey(key);

        if (userNamespaceAuthorizationEntity == null)
        {
            throw new ObjectNotFoundException(
                String.format("User namespace authorization with user id \"%s\" and namespace \"%s\" doesn't exist.", key.getUserId(), key.getNamespace()));
        }

        return userNamespaceAuthorizationEntity;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy