/*
 * The aspiredb project
 * 
 * Copyright (c) 2012 University of British Columbia
 * 
 * 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 ubc.pavlab.aspiredb.server.security.authorization.acl;

import gemma.gsec.AuthorityConstants;
import gemma.gsec.acl.BaseAclAdvice;
import gemma.gsec.acl.domain.AclGrantedAuthoritySid;
import gemma.gsec.model.Securable;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import ubc.pavlab.aspiredb.server.model.common.auditAndSecurity.GroupAuthority;
import ubc.pavlab.aspiredb.server.model.common.auditAndSecurity.User;
import ubc.pavlab.aspiredb.server.model.common.auditAndSecurity.UserGroup;

/**
 * Adds security controls to newly created objects, and removes them for objects that are deleted. Methods in this
 * interceptor are run for all new objects (to add security if needed) and when objects are deleted. This is not used to
 * modify permissions on existing objects.
 * <p>
 * Implementation Note: For permissions modification to be triggered, the method name must match certain patterns, which
 * include "create", or "remove". These patterns are defined in the {@link AclPointcut}. Other methods that would
 * require changes to permissions will not work without modifying the source code.
 */
@Component
public class AclAdvice extends BaseAclAdvice {

    private static Log log = LogFactory.getLog( AclAdvice.class );

    /*
     * (non-Javadoc)
     * 
     * @see gemma.gsec.acl.BaseAclAdvice#getUserGroupGrantedAuthority(gemma.gsec.model.Securable)
     */
    @Override
    protected GrantedAuthority getUserGroupGrantedAuthority( Securable object ) {
        Collection<GroupAuthority> authorities = ( ( UserGroup ) object ).getAuthorities();
        assert authorities.size() == 1;
        GrantedAuthority ga = new SimpleGrantedAuthority( authorities.iterator().next().getAuthority() );
        return ga;
    }

    /*
     * (non-Javadoc)
     * 
     * @see gemma.gsec.acl.BaseAclAdvice#getUserName(gemma.gsec.model.Securable)
     */
    @Override
    protected String getUserName( Securable user ) {
        return ( ( User ) user ).getUserName();
    }

    /*
     * (non-Javadoc)
     * 
     * @see gemma.gsec.acl.BaseAclAdvice#objectIsUser(gemma.gsec.model.Securable)
     */
    @Override
    protected boolean objectIsUser( Securable object ) {
        return User.class.isAssignableFrom( object.getClass() );
    }

    /*
     * (non-Javadoc)
     * 
     * @see gemma.gsec.acl.BaseAclAdvice#objectIsUserGroup(gemma.gsec.model.Securable)
     */
    @Override
    protected boolean objectIsUserGroup( Securable object ) {
        return UserGroup.class.isAssignableFrom( object.getClass() );
    }
    
}
@@ -732,16 +732,51 @@
 stants;%0A
+import gemma.gsec.SecurityService;%0A
 import g
@@ -800,24 +800,24 @@
 eAclAdvice;%0A
-
 import gemma
@@ -891,16 +891,54 @@
 curable;
+%0Aimport gemma.gsec.model.SecuredChild;
 %0A%0Aimport
@@ -1046,16 +1046,79 @@
 actory;%0A
+import org.springframework.beans.factory.annotation.Autowired;%0A
 import o
@@ -2428,16 +2428,73 @@
 vice %7B%0A%0A
+    @Autowired%0A    SecurityService securityService;%0A    %0A
     priv
@@ -3854,14 +3854,564 @@
 ;%0A    %7D%0A
-
     %0A
+    /**%0A     * Certain objects are not made public immediately on creation by administrators. The default implementation returns%0A     * true if clazz is assignable to SecuredChild; otherwise false. Subclasses overriding this method should probably%0A     * call super.specialCaseToKeepPrivateOnCreation()%0A     * %0A     * @param clazz%0A     * @return true if it's a special case to be kept private on creation.%0A     */%0A    @Override%0A    protected boolean specialCaseToKeepPrivateOnCreation( Class%3C? extends Securable%3E clazz ) %7B%0A        return true;%0A    %7D%0A
 %7D

Make securables private on creation