com.hypersocket.permissions.PermissionRepositoryImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.hypersocket.permissions.PermissionRepositoryImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Hypersocket Limited.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 ******************************************************************************/
package com.hypersocket.permissions;

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

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.hypersocket.properties.ResourceKeyRestriction;
import com.hypersocket.realm.Principal;
import com.hypersocket.realm.Realm;
import com.hypersocket.realm.RealmRestriction;
import com.hypersocket.repository.AbstractRepositoryImpl;
import com.hypersocket.repository.CriteriaConfiguration;
import com.hypersocket.repository.DetachedCriteriaConfiguration;
import com.hypersocket.repository.DistinctRootEntity;
import com.hypersocket.repository.HiddenCriteria;
import com.hypersocket.tables.ColumnSort;

@Repository
public class PermissionRepositoryImpl extends AbstractRepositoryImpl<Long> implements PermissionRepository {

    DetachedCriteriaConfiguration JOIN_PERMISSIONS = new DetachedCriteriaConfiguration() {
        @Override
        public void configure(DetachedCriteria criteria) {
            criteria.setFetchMode("permissions", FetchMode.SELECT);
            criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        }
    };

    DetachedCriteriaConfiguration JOIN_PRINCIPALS_PERMISSIONS = new DetachedCriteriaConfiguration() {
        @Override
        public void configure(DetachedCriteria criteria) {
            criteria.setFetchMode("permissions", FetchMode.SELECT);
            criteria.setFetchMode("principals", FetchMode.SELECT);
            criteria.setFetchMode("resources", FetchMode.SELECT);
            criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        }
    };

    DetachedCriteriaConfiguration JOIN_ROLES = new DetachedCriteriaConfiguration() {
        @Override
        public void configure(DetachedCriteria criteria) {
            criteria.setFetchMode("roles", FetchMode.SELECT);
            criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        }
    };

    @Override
    @Transactional
    public PermissionCategory createCategory(String resourceBundle, String resourceKey) {

        PermissionCategory category = new PermissionCategory();
        category.setResourceBundle(resourceBundle);
        category.setResourceKey(resourceKey);
        save(category);
        return category;
    }

    @Override
    @Transactional
    public Permission createPermission(String name, boolean system, PermissionCategory category, boolean hidden) {

        Permission permission = new Permission();
        permission.setResourceKey(name);
        permission.setCategory(category);
        permission.setHidden(hidden);
        permission.setSystem(system);
        save(permission);
        flush();
        refresh(permission);
        return permission;
    }

    @Override
    @Transactional
    public Role createRole(String name, Realm realm) {
        return createRole(name, realm, false, false, false, false);
    }

    @Override
    @Transactional
    public Role createRole(String name, Realm realm, boolean personalRole, boolean allUsers, boolean allPermissions,
            boolean system) {

        Role role = new Role();
        role.setName(name);
        role.setRealm(realm);
        role.setResourceCategory("role");
        role.setPersonalRole(personalRole);
        role.setAllUsers(allUsers);
        role.setAllPermissions(allPermissions);
        role.setSystem(system);

        save(role);
        return role;
    }

    @Override
    @Transactional
    public void updateRole(Role role, Set<Principal> unassignPrincipals, Set<Principal> assignPrincipals,
            Set<Permission> revokePermissions, Set<Permission> grantPermissions) {
        role.setResourceCategory("role");
        save(role);
        unassignRole(role, unassignPrincipals.toArray(new Principal[0]));
        assignRole(role, assignPrincipals.toArray(new Principal[0]));
        revokePermission(role, revokePermissions);
        grantPermissions(role, grantPermissions);
    }

    @Override
    @Transactional
    public void saveRole(Role role, Realm realm, Principal[] principals, Collection<Permission> permissions) {
        role.setResourceCategory("role");
        save(role);
        assignRole(role, principals);
        grantPermissions(role, permissions);
    }

    @Transactional
    @Override
    public void createRole(String name, Realm realm, boolean personalRole, boolean allUsers, boolean allPermissions,
            boolean system, Set<Permission> permissions) {
        Role role = createRole(name, realm, personalRole, allUsers, allPermissions, system);
        role.setPermissions(permissions);
        save(role);
    }

    @Override
    @Transactional(readOnly = true)
    public PermissionCategory getCategoryByKey(String resourceBundle, String resourceKey) {
        return get("resourceBundle", resourceBundle, PermissionCategory.class,
                new ResourceKeyRestriction(resourceKey), new DistinctRootEntity());
    }

    @Override
    @Transactional(readOnly = true)
    public PermissionCategory getCategoryById(Long id) {
        return getCategory("id", id);
    }

    protected PermissionCategory getCategory(String column, Object value) {
        return get(column, value, PermissionCategory.class, JOIN_PERMISSIONS);
    }

    @Override
    @Transactional(readOnly = true)
    public Permission getPermissionByResourceKey(String name) {
        return getPermission("resourceKey", name);
    }

    @Override
    @Transactional(readOnly = true)
    public Permission getPermissionById(Long id) {
        return getPermission("id", id);
    }

    protected Permission getPermission(String column, Object value) {
        return get(column, value, Permission.class, JOIN_ROLES);
    }

    @Override
    @Transactional(readOnly = true)
    public Role getRoleByName(String name, Realm realm) {
        return get("name", name, Role.class, JOIN_PRINCIPALS_PERMISSIONS, new RealmRestriction(realm));
    }

    @Override
    @Transactional(readOnly = true)
    public Role getRoleById(Long id) {
        return get("id", id, Role.class, JOIN_PRINCIPALS_PERMISSIONS);
    }

    @Override
    @Transactional
    public void grantPermission(Role role, Permission permission) {
        role.getPermissions().add(permission);
        save(role);
    }

    @Override
    @Transactional
    public void revokePermission(Role role, Permission permission) {
        role.getPermissions().remove(permission);
        save(role);
    }

    @Override
    @Transactional
    public void grantPermissions(Role role, Collection<Permission> permissions) {
        role.getPermissions().addAll(permissions);
        save(role);
    }

    @Override
    @Transactional
    public void revokePermission(Role role, Collection<Permission> permissions) {
        role.getPermissions().removeAll(permissions);
        save(role);
    }

    @Override
    @Transactional
    public void deleteCategory(PermissionCategory category) {
        delete(category);
    }

    @Override
    @Transactional
    public void deletePermission(Permission permission) {
        delete(permission);
    }

    @Override
    @Transactional
    public void deleteRole(Role role) {
        delete(role);
    }

    @Override
    @Transactional(readOnly = true)
    public List<PermissionCategory> getAllCatgories() {
        return allEntities(PermissionCategory.class, JOIN_PERMISSIONS);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Permission> getAllPermissions(final Set<Long> permissions, final boolean includeSystem) {
        return allEntities(Permission.class, new DetachedCriteriaConfiguration() {
            @Override
            public void configure(DetachedCriteria criteria) {
                if (!includeSystem) {
                    criteria.add(
                            Restrictions.and(Restrictions.eq("system", false), Restrictions.in("id", permissions)));
                } else {
                    criteria.add(Restrictions.in("id", permissions));
                }
            }
        }, JOIN_ROLES, new HiddenCriteria(false));
    }

    @Override
    @Transactional
    public void saveRole(Role role) {
        role.setResourceCategory("role");
        save(role);
    }

    @Override
    @Transactional
    public void assignRole(Role role, Principal... principals) {

        for (Principal p : principals) {
            role.getPrincipals().add(p);
        }

        save(role);

    }

    @Override
    @Transactional
    public void unassignRole(Role role, Principal... principals) {
        for (Principal p : principals) {
            role.getPrincipals().remove(p);
        }

        save(role);

    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public Set<Permission> getPrincipalPermissions(Collection<Principal> principals,
            PermissionType... permissionTypes) {

        if (principals == null) {
            return new HashSet<Permission>();
        }

        Criteria crit = createCriteria(Permission.class)
                .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

        List<String> list = new ArrayList<String>();
        for (PermissionType t : permissionTypes) {
            list.add(t.getResourceKey());
        }

        if (list.size() > 0) {
            crit = crit.add(Restrictions.in("resourceKey", list));
        }

        List<Long> ids = new ArrayList<Long>();
        for (Principal p : principals) {
            ids.add(p.getId());
        }

        crit = crit.createCriteria("roles").createCriteria("principals").add(Restrictions.in("id", ids));

        return new HashSet<Permission>(crit.list());

    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public Set<Principal> getPrincipalsWithPermissions(PermissionType permission) {

        Criteria crit = createCriteria(Principal.class)
                .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY).createCriteria("roles")
                .createCriteria("permissions").add(Restrictions.eq("resourceKey", permission.getResourceKey()));

        return new HashSet<Principal>(crit.list());
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public Set<Role> getRolesWithPermissions(PermissionType permission) {

        Criteria crit = createCriteria(Role.class).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
                .createCriteria("permissions").add(Restrictions.eq("resourceKey", permission.getResourceKey()));

        return new HashSet<Role>(crit.list());
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public Set<Role> getRolesWithPermissions(Permission permission) {

        Criteria crit = createCriteria(Role.class).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
                .createCriteria("permissions").add(Restrictions.eq("resourceKey", permission.getResourceKey()));

        return new HashSet<Role>(crit.list());
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public Set<Principal> getPrincipalsWithPermissions(Permission permission) {

        Criteria crit = createCriteria(Principal.class)
                .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY).createCriteria("roles")
                .createCriteria("permissions").add(Restrictions.eq("resourceKey", permission.getResourceKey()));

        return new HashSet<Principal>(crit.list());
    }

    @Override
    @Transactional(readOnly = true)
    public List<Role> getRolesForRealm(Realm realm) {
        return allEntities(Role.class, JOIN_PRINCIPALS_PERMISSIONS, new RealmRestriction(realm),
                new DetachedCriteriaConfiguration() {
                    @Override
                    public void configure(DetachedCriteria criteria) {
                        criteria.add(Restrictions.eq("personalRole", false));
                        criteria.add(Restrictions.eq("hidden", false));
                    }
                });
    }

    @Override
    @Transactional(readOnly = true)
    public List<Role> searchRoles(final Realm realm, String searchPattern, int start, int length,
            ColumnSort[] sorting) {
        return search(Role.class, "name", searchPattern, start, length, sorting, new CriteriaConfiguration() {

            @Override
            public void configure(Criteria criteria) {
                criteria.add(Restrictions.eq("personalRole", false));
                criteria.add(Restrictions.eq("hidden", false));
                criteria.setFetchMode("permissions", FetchMode.SELECT);
                criteria.setFetchMode("principals", FetchMode.SELECT);
                criteria.setFetchMode("resources", FetchMode.SELECT);
                criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
                criteria.add(Restrictions.eq("realm", realm));
            }
        });
    }

    @Override
    @Transactional(readOnly = true)
    public Long countRoles(final Realm realm, String searchPattern) {
        return getCount(Role.class, "name", searchPattern, new CriteriaConfiguration() {

            @Override
            public void configure(Criteria criteria) {
                criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
                criteria.add(Restrictions.eq("personalRole", false));
                criteria.add(Restrictions.eq("hidden", false));
                criteria.add(Restrictions.or(Restrictions.eq("realm", realm), Restrictions.isNull("realm")));
            }
        });
    }

    @Override
    @Transactional(readOnly = true)
    public List<Permission> getPermissionsByCategory(final PermissionCategory category) {
        return allEntities(Permission.class, JOIN_ROLES, new DetachedCriteriaConfiguration() {

            @Override
            public void configure(DetachedCriteria criteria) {
                criteria.add(Restrictions.eq("category", category));

            }
        });
    }

    private Role createPersonalRole(Principal principal) {
        Role r = createRole(principal.getRealm().getName() + "/" + principal.getPrincipalName(),
                principal.getRealm(), true, false, false, false);
        assignRole(r, principal);
        return r;
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional
    public Role getPersonalRole(Principal principal) {

        Criteria crit = createCriteria(Role.class).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
                .add(Restrictions.eq("personalRole", true)).createCriteria("principals")
                .add(Restrictions.in("id", Arrays.asList(principal.getId())));

        Set<Role> roles = new HashSet<Role>(crit.list());

        if (roles.isEmpty()) {
            return createPersonalRole(principal);
        } else {
            return roles.iterator().next();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional(readOnly = true)
    public Set<Role> getRolesForPrincipal(List<Principal> principals) {

        if (principals == null) {
            return new HashSet<Role>();
        }

        Criteria crit = createCriteria(Role.class).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

        List<Long> ids = new ArrayList<Long>();
        for (Principal p : principals) {
            ids.add(p.getId());
        }

        crit = crit.createCriteria("principals").add(Restrictions.in("id", ids));

        Set<Role> roles = new HashSet<Role>(crit.list());
        roles.addAll(getAllUserRoles(principals.get(0).getRealm()));
        return roles;
    }

    @Override
    @Transactional(readOnly = true)
    public Set<Role> getAllUserRoles(Realm realm) {

        return new HashSet<Role>(allEntities(Role.class, JOIN_PRINCIPALS_PERMISSIONS, new RealmRestriction(realm),
                new DetachedCriteriaConfiguration() {
                    @Override
                    public void configure(DetachedCriteria criteria) {
                        criteria.add(Restrictions.eq("allUsers", true));
                    }
                }));
    }

}