/*
 * Copyright 2012 Shared Learning Collaborative, LLC
 *
 * 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.slc.sli.api.security.context.resolver;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.slc.sli.api.config.EntityDefinition;
import org.slc.sli.api.config.EntityDefinitionStore;
import org.slc.sli.api.security.schema.SchemaDataProvider;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.NeutralQuery;
import org.slc.sli.api.security.context.PagingRepositoryDelegate;

/**
 * Resolves "Users" to anything.
 *
 * In particular we only want Users to resolve to administrative resources and be
 * denied to anything else.
 *
 * @author rlatta
 *
 */
@Component
public class UserToAnythingResolver implements EntityContextResolver {
    private String toEntity;
    private static final String ADMIN_SPHERE = "Admin";
    private static final String PUBLIC_SPHERE = "Public";
    @Autowired
    private EntityDefinitionStore store;

    @Autowired
    private SchemaDataProvider provider;

    @Autowired
    
    private PagingRepositoryDelegate<Entity> repository;

    /* (non-Javadoc)
     * @see org.slc.sli.api.security.context.resolver.EntityContextResolver#canResolve(java.lang.String, java.lang.String)
     */
    @Override
    public boolean canResolve(String fromEntityType, String toEntityType) {
        this.toEntity = toEntityType;
        debug("Resolving {} -> {}", new String[] { fromEntityType, toEntityType });
        return (fromEntityType.equals("user") || fromEntityType.equals("admin-staff"));
    }

    /* (non-Javadoc)
     * @see org.slc.sli.api.security.context.resolver.EntityContextResolver#findAccessible(org.slc.sli.domain.Entity)
     */
    @Override
    public List<String> findAccessible(Entity principal) {
        EntityDefinition def = store.lookupByEntityType(toEntity);

        if (PUBLIC_SPHERE.equals(provider.getDataSphere(def.getType()))) {
            info("Granting public sphere to resource: {}", def.getResourceName());
        } else if (ADMIN_SPHERE.equals(provider.getDataSphere(def.getType()))) {
            info("Granting admin sphere to resource: {}", def.getResourceName());
        } else {
            info("Denying access to all entities of type {}", toEntity);
            return new ArrayList<String>();
        }
        // We give access to all admin or to public
        List<String> ids = new ArrayList<String>();

        Iterable<String> it = this.repository.findAllIds(def.getStoredCollectionName(), new NeutralQuery());
        for (String id : it) {
            ids.add(id);
        }
        return ids;
    }

}

@@ -938,16 +938,81 @@
 nStore;%0A
+import org.slc.sli.api.resources.security.SecurityEventResource;%0A
 import o
@@ -1062,16 +1062,16 @@
 ovider;%0A
-
 import o
@@ -1463,16 +1463,21 @@
 olver %7B%0A
+    %0A
     priv
@@ -1480,22 +1480,42 @@
 private 
+static ThreadLocal%3C
 String
+%3E
  toEntit
@@ -1515,16 +1515,44 @@
 toEntity
+ = new ThreadLocal%3CString%3E()
 ;%0A    pr
@@ -1659,16 +1659,21 @@
 ublic%22;%0A
+    %0A
     @Aut
@@ -1793,21 +1793,16 @@
 towired%0A
-    %0A
     priv
@@ -2105,38 +2105,206 @@
     
-this.toEntity = toEntityType;%0A
+if (toEntityType.equals(SecurityEventResource.RESOURCE_NAME)) %7B%0A            return false;%0A        %7D%0A        %0A        if (fromEntityType.equals(%22user%22) %7C%7C fromEntityType.equals(%22admin-staff%22)) %7B%0A    
     
@@ -2338,23 +2338,8 @@
 %7B%7D%22,
- new String%5B%5D %7B
  fro
@@ -2363,18 +2363,16 @@
 tityType
- %7D
 );%0A     
@@ -2378,87 +2378,117 @@
     
-return (fromEntityType.equals(%22user%22) %7C%7C fromEntityType.equals(%22admin-staff%22));
+    toEntity.set(toEntityType);%0A            return true;%0A        %7D else %7B%0A            return false;%0A        %7D
 %0A   
@@ -2775,16 +2775,22 @@
 toEntity
+.get()
 );%0A%0A    
@@ -3520,16 +3520,16 @@
 dd(id);%0A
-
         
@@ -3522,32 +3522,59 @@
 (id);%0A        %7D%0A
+        toEntity.remove();%0A
         return i

Fix intermittent failure in security event tests