com.trailmagic.image.security.SpringSecurityImageSecurityService.java Source code

Java tutorial

Introduction

Here is the source code for com.trailmagic.image.security.SpringSecurityImageSecurityService.java

Source

/*
 * Copyright (c) 2006 Oliver Stewart.  All Rights Reserved.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This file is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
package com.trailmagic.image.security;

import com.trailmagic.image.Image;
import com.trailmagic.image.ImageFrame;
import com.trailmagic.image.ImageGroup;
import com.trailmagic.image.ImageGroupRepository;
import com.trailmagic.user.Owned;
import com.trailmagic.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.GrantedAuthoritySid;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.*;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Transactional
public class SpringSecurityImageSecurityService implements ImageSecurityService {
    private MutableAclService aclService;
    private ImageGroupRepository imageGroupRepository;
    private ObjectIdentityRetrievalStrategy identityRetrievalStrategy;
    private static Logger log = LoggerFactory.getLogger(SpringSecurityImageSecurityService.class);
    private static final Set<Permission> OWNER_PERMISSIONS = new HashSet<Permission>();
    private static final String ROLE_EVERYONE = "ROLE_EVERYONE";
    private static final GrantedAuthoritySid PUBLIC_SID = new GrantedAuthoritySid(ROLE_EVERYONE);

    static {
        OWNER_PERMISSIONS.add(BasePermission.READ);
        OWNER_PERMISSIONS.add(BasePermission.WRITE);
        OWNER_PERMISSIONS.add(BasePermission.CREATE);
        OWNER_PERMISSIONS.add(BasePermission.DELETE);
        OWNER_PERMISSIONS.add(BasePermission.ADMINISTRATION);
    }

    public SpringSecurityImageSecurityService(MutableAclService aclService,
            ImageGroupRepository imageGroupRepository, ObjectIdentityRetrievalStrategy identityRetrievalStrategy) {
        this.aclService = aclService;
        this.imageGroupRepository = imageGroupRepository;
        this.identityRetrievalStrategy = identityRetrievalStrategy;
    }

    public void makeImagesPublic(ImageGroup group) {
        log.info("Making all images in " + group.getType() + " public: " + group);

        for (ImageFrame frame : group.getFrames()) {
            log.info("Making image public: " + frame.getImage());
            makePublic(frame.getImage());
        }
    }

    public void makeImagesPrivate(ImageGroup group) {
        log.info("Making all images in " + group.getType() + " private: " + group);
        for (ImageFrame frame : group.getFrames()) {
            log.info("Making image private: " + frame.getImage());
            makePrivate(frame.getImage());
        }
    }

    @Secured("ACL_OBJECT_ADMIN")
    public void makePublic(AccessControlled obj) {
        addReadPermission(obj, ROLE_EVERYONE);
        log.info("Added access to " + obj + " by ROLE_EVERYONE");
    }

    @Secured("ROLE_USER")
    public void addOwnerAcl(Image image) {
        addOwnerAclInternal(image, imageGroupRepository.getRollForImage(image));
    }

    @Secured("ROLE_USER")
    public void addOwnerAcl(ImageGroup group) {
        addOwnerAclInternal(group, null);
    }

    private void addOwnerAclInternal(Owned ownedObj, Object parent) {
        final User owner = ownedObj.getOwner();
        final ObjectIdentity identity = identityRetrievalStrategy.getObjectIdentity(ownedObj);
        final MutableAcl acl = aclService.createAcl(identity);
        final Sid ownerSid = sidForUser(owner);
        acl.setOwner(ownerSid);
        aclService.updateAcl(acl);

        if (parent != null) {
            final ObjectIdentity parentIdentity = identityRetrievalStrategy.getObjectIdentity(parent);
            if (parentIdentity != null) {
                try {
                    final Acl parentAcl = aclService.readAclById(parentIdentity, Arrays.asList(ownerSid));
                    acl.setParent(parentAcl);
                } catch (NotFoundException e) {
                    // don't care
                }
            }
        }
        effectPermissions(acl, ownerSid, OWNER_PERMISSIONS, false);
    }

    @Transactional(readOnly = true)
    public boolean isPublic(Object obj) {
        return isGranted(obj, PUBLIC_SID, BasePermission.READ);
    }

    @Transactional(readOnly = true)
    public boolean isReadableByUser(Object target, User recipient) {
        return isGranted(target, recipient, BasePermission.READ);
    }

    @Transactional(readOnly = true)
    public boolean isAvailableToUser(Object target, User recipient, Permission permission) {
        return isGranted(target, recipient, permission);
    }

    @Transactional(readOnly = true)
    public boolean isReadableByRole(Object target, String role) {
        return isGranted(target, role, BasePermission.READ);
    }

    @Transactional(readOnly = true)
    public boolean isAvailableToRole(Object target, String role, Permission permission) {
        return isGranted(target, role, permission);
    }

    private boolean isGranted(Object target, User recipient, Permission permission) {
        return isGranted(target, sidForUser(recipient), permission);
    }

    private boolean isGranted(Object target, String recipientRole, Permission permission) {
        return isGranted(target, sidForRole(recipientRole), permission);
    }

    private boolean isGranted(Object target, Sid recipient, Permission permission) {
        List<Sid> sids = Arrays.asList(recipient);
        try {
            final Acl acl = aclService.readAclById(identityRetrievalStrategy.getObjectIdentity(target), sids);
            return acl != null && acl.isGranted(Arrays.asList(permission), sids, false);
        } catch (NotFoundException e) {
            return false;
        }
    }

    @Secured("ACL_OBJECT_ADMIN")
    public void addReadPermission(Object obj, String recipientRole) {
        addPermission(obj, recipientRole, BasePermission.READ);
    }

    @Secured("ACL_OBJECT_ADMIN")
    public void addReadPermission(Object obj, User recipient) {
        addPermission(obj, recipient, BasePermission.READ);
    }

    public void addPermission(Object obj, String recipientRole, Permission permission) {
        final Sid sid = sidForRole(recipientRole);
        effectPermission(findAcl(obj, sid), sid, permission, false);
    }

    private Sid sidForRole(String recipientRole) {
        return new GrantedAuthoritySid(recipientRole);
    }

    public void addPermissions(Object obj, User recipient, Set<Permission> permissions) {
        final Sid sid = sidForUser(recipient);
        effectPermissions(findAcl(obj, sid), sid, permissions, false);
    }

    private Sid sidForUser(User recipient) {
        return new PrincipalSid(recipient.getScreenName());
    }

    private void addPermission(Object obj, User recipient, Permission permission) {
        addPermission(obj, recipient, permission, true);
    }

    private void addPermission(Object obj, User recipient, Permission permission, boolean additive) {
        final Sid principalSid = sidForUser(recipient);
        effectPermission(findAcl(obj, principalSid), principalSid, permission, additive);
    }

    private void effectPermission(MutableAcl acl, Sid recipient, Permission permission, boolean additive) {
        effectPermissions(acl, recipient, Collections.singleton(permission), additive);
    }

    public void effectPermissions(MutableAcl acl, Sid recipient, Set<Permission> newPermissions, boolean additive) {
        Set<Permission> existingPermissions = findExistingPermissions(acl, recipient);

        if (!additive) {
            Set<Permission> permsToRemove = new HashSet<Permission>();
            permsToRemove.addAll(existingPermissions);
            permsToRemove.removeAll(newPermissions);
            for (Permission perm : permsToRemove) {
                acl.deleteAce(indexOf(recipient, perm, acl));
                if (log.isDebugEnabled()) {
                    log.debug("Removed ACE for permission " + perm + ", recipient " + recipient + ", on object "
                            + acl.getObjectIdentity());
                }

            }
        }

        Set<Permission> permsToAdd = new HashSet<Permission>();
        permsToAdd.addAll(newPermissions);
        permsToAdd.removeAll(existingPermissions);
        for (Permission perm : permsToAdd) {
            acl.insertAce(acl.getEntries().size(), perm, recipient, true);
            if (log.isDebugEnabled()) {
                log.debug("Added ACE for permission " + perm + ", recipient " + recipient + ", on object "
                        + acl.getObjectIdentity());
            }

        }
        aclService.updateAcl(acl);
    }

    private Set<Permission> findExistingPermissions(MutableAcl acl, Sid recipient) {
        Set<Permission> existingPermissions = new HashSet<Permission>();
        for (AccessControlEntry entry : acl.getEntries()) {
            if (entry.getSid().equals(recipient)) {
                existingPermissions.add(entry.getPermission());
            }
        }
        return existingPermissions;
    }

    private int indexOf(Sid recipient, Permission permission, MutableAcl acl) {
        final List<AccessControlEntry> entries = acl.getEntries();
        for (int i = 0; i < entries.size(); i++) {
            final AccessControlEntry entry = entries.get(i);
            if (entry.getSid().equals(recipient) && permission.equals(entry.getPermission())) {
                return i;
            }
        }
        return -1;
    }

    private MutableAcl findAcl(Object obj, Sid sid) {
        final ObjectIdentity identity = identityRetrievalStrategy.getObjectIdentity(obj);
        return (MutableAcl) aclService.readAclById(identity, Arrays.asList(sid));
    }

    @Secured("ACL_OBJECT_ADMIN")
    public void makePrivate(AccessControlled obj) {
        final Sid sid = sidForRole(ROLE_EVERYONE);
        effectPermissions(findAcl(obj, sid), sid, Collections.<Permission>emptySet(), false);
        log.info("Removed access to " + obj + " by ROLE_EVERYONE");
    }

}