<commit_before>/*
 * 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.oauth;

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

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

import org.slc.sli.api.constants.EntityNames;
import org.slc.sli.api.security.SLIPrincipal;
import org.slc.sli.api.security.context.resolver.EdOrgHelper;
import org.slc.sli.api.util.SecurityUtil;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.NeutralCriteria;
import org.slc.sli.domain.NeutralQuery;
import org.slc.sli.domain.Repository;

/**
 * Determines which applications a given user is authorized to use based on
 * that user's ed-org.
 *
 * @author pwolf
 *
 */
@Component
public class ApplicationAuthorizationValidator {

    @Autowired
    @Qualifier("validationRepo")
    private Repository<Entity> repo;

    @Autowired
    private EdOrgHelper helper;

    /**
     * Get the list of authorized apps for the user based on the user's LEA.
     *
     * No additional filtering is done on the results. E.g. if a user is a non-admin,
     * the admin apps will still show up in the list, or if an app is disabled it will
     * still show up.
     *
     * @param principal
     *
     * @return list of app IDs, or null if it couldn't be determined
     */
    @SuppressWarnings("unchecked")
    public List<String> getAuthorizedApps(SLIPrincipal principal) {

        boolean isHostedUser = SecurityUtil.isHostedUser(repo, principal);

        //For hosted users (Developer, SLC Operator, SEA/LEA Administrator) they're not associated with a district
        List<Entity> districts = isHostedUser ? new ArrayList<Entity>() : findUsersDistricts(principal);

        Set<String> bootstrapApps = getDefaultAllowedApps(principal.isAdminUser());
        Set<String> results = isHostedUser ? new HashSet<String>() : getDefaultAuthorizedApps();

        for (Entity district : districts) {
            debug("User is in district {}.", district.getEntityId());

            NeutralQuery appAuthCollQuery = new NeutralQuery();
            appAuthCollQuery.addCriteria(new NeutralCriteria("authId", "=", district.getEntityId()));
            appAuthCollQuery.addCriteria(new NeutralCriteria("authType", "=", "EDUCATION_ORGANIZATION"));
            Entity authorizedApps = repo.findOne("applicationAuthorization", appAuthCollQuery);

            if (authorizedApps != null) {

                NeutralQuery appCollQuery = new NeutralQuery(0);
                appCollQuery.addCriteria(new NeutralCriteria("authorized_ed_orgs", "=", district.getEntityId()));
                if (!principal.isAdminUser()) {
                    appCollQuery.addCriteria(new NeutralCriteria("is_admin", "=", false));
                }

                Set<String> vendorAppsEnabledForEdorg = new HashSet<String>(bootstrapApps); //bootstrap apps automatically added

                for (String id : repo.findAllIds("application", appCollQuery)) {
                    vendorAppsEnabledForEdorg.add(id);
                }

                //Intersection
                vendorAppsEnabledForEdorg.retainAll((List<String>) authorizedApps.getBody().get("appIds"));

                results.addAll(vendorAppsEnabledForEdorg);
            }
        }

        if (isHostedUser) {

            NeutralQuery adminVisible = new NeutralQuery(0);
            adminVisible.addCriteria(new NeutralCriteria("admin_visible", "=", true));
            for (String id : repo.findAllIds("application", adminVisible)) {
                results.add(id);
            }

        }

        return new ArrayList<String>(results);
    }

    /**
     * These are the apps that are auto-authorized, i.e. the district admin doesn't
     * need to manually authorize the application.
     * @return
     */
    private Set<String> getDefaultAuthorizedApps() {
        Set<String> toReturn = new HashSet<String>();
        NeutralQuery autoAuthQuery = new NeutralQuery(0);
        autoAuthQuery.addCriteria(new NeutralCriteria("authorized_for_all_edorgs", "=", true));
        Iterable<Entity> autoAuthApps = repo.findAll("application", autoAuthQuery);

        for (Entity currentApp : autoAuthApps) {
            toReturn.add(currentApp.getEntityId());
        }
        return toReturn;
    }

    /**
     * These are apps that are auto-allowed, i.e. the app developer doesn't need
     * to select the districts that can use the app.
     * @return
     */
    private Set<String> getDefaultAllowedApps(boolean allowAdmin) {
        Set<String> toReturn = new HashSet<String>();
        NeutralQuery bootstrapQuery = new NeutralQuery(0);
        bootstrapQuery.addCriteria(new NeutralCriteria("allowed_for_all_edorgs", "=", true));
        if (!allowAdmin) {
            bootstrapQuery.addCriteria(new NeutralCriteria("is_admin", "=", false));
        }
        Iterable<Entity> bootstrapApps = repo.findAll("application", bootstrapQuery);

        for (Entity currentApp : bootstrapApps) {
            toReturn.add(currentApp.getEntityId());
        }<commit_msg>Undid the changes to deny use of admin application to non-admin users.<commit_after>/*
 * 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.oauth;

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

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

import org.slc.sli.api.constants.EntityNames;
import org.slc.sli.api.security.SLIPrincipal;
import org.slc.sli.api.security.context.resolver.EdOrgHelper;
import org.slc.sli.api.util.SecurityUtil;
import org.slc.sli.domain.Entity;
import org.slc.sli.domain.NeutralCriteria;
import org.slc.sli.domain.NeutralQuery;
import org.slc.sli.domain.Repository;

/**
 * Determines which applications a given user is authorized to use based on
 * that user's ed-org.
 *
 * @author pwolf
 *
 */
@Component
public class ApplicationAuthorizationValidator {

    @Autowired
    @Qualifier("validationRepo")
    private Repository<Entity> repo;

    @Autowired
    private EdOrgHelper helper;

    /**
     * Get the list of authorized apps for the user based on the user's LEA.
     *
     * No additional filtering is done on the results. E.g. if a user is a non-admin,
     * the admin apps will still show up in the list, or if an app is disabled it will
     * still show up.
     *
     * @param principal
     *
     * @return list of app IDs, or null if it couldn't be determined
     */
    @SuppressWarnings("unchecked")
    public List<String> getAuthorizedApps(SLIPrincipal principal) {

        boolean isHostedUser = SecurityUtil.isHostedUser(repo, principal);

        //For hosted users (Developer, SLC Operator, SEA/LEA Administrator) they're not associated with a district
        List<Entity> districts = isHostedUser ? new ArrayList<Entity>() : findUsersDistricts(principal);

        Set<String> bootstrapApps = getDefaultAllowedApps();
        Set<String> results = isHostedUser ? new HashSet<String>() : getDefaultAuthorizedApps();

        for (Entity district : districts) {
            debug("User is in district {}.", district.getEntityId());

            NeutralQuery appAuthCollQuery = new NeutralQuery();
            appAuthCollQuery.addCriteria(new NeutralCriteria("authId", "=", district.getEntityId()));
            appAuthCollQuery.addCriteria(new NeutralCriteria("authType", "=", "EDUCATION_ORGANIZATION"));
            Entity authorizedApps = repo.findOne("applicationAuthorization", appAuthCollQuery);

            if (authorizedApps != null) {

                NeutralQuery appCollQuery = new NeutralQuery(0);
                appCollQuery.addCriteria(new NeutralCriteria("authorized_ed_orgs", "=", district.getEntityId()));

                Set<String> vendorAppsEnabledForEdorg = new HashSet<String>(bootstrapApps); //bootstrap apps automatically added

                for (String id : repo.findAllIds("application", appCollQuery)) {
                    vendorAppsEnabledForEdorg.add(id);
                }

                //Intersection
                vendorAppsEnabledForEdorg.retainAll((List<String>) authorizedApps.getBody().get("appIds"));

                results.addAll(vendorAppsEnabledForEdorg);
            }
        }

        if (isHostedUser) {

            NeutralQuery adminVisible = new NeutralQuery(0);
            adminVisible.addCriteria(new NeutralCriteria("admin_visible", "=", true));
            for (String id : repo.findAllIds("application", adminVisible)) {
                results.add(id);
            }

        }

        return new ArrayList<String>(results);
    }

    /**
     * These are the apps that are auto-authorized, i.e. the district admin doesn't
     * need to manually authorize the application.
     * @return
     */
    private Set<String> getDefaultAuthorizedApps() {
        Set<String> toReturn = new HashSet<String>();
        NeutralQuery autoAuthQuery = new NeutralQuery(0);
        autoAuthQuery.addCriteria(new NeutralCriteria("authorized_for_all_edorgs", "=", true));
        Iterable<Entity> autoAuthApps = repo.findAll("application", autoAuthQuery);

        for (Entity currentApp : autoAuthApps) {
            toReturn.add(currentApp.getEntityId());
        }
        return toReturn;
    }

    /**
     * These are apps that are auto-allowed, i.e. the app developer doesn't need
     * to select the districts that can use the app.
     * @return
     */
    private Set<String> getDefaultAllowedApps() {
        Set<String> toReturn = new HashSet<String>();
        NeutralQuery bootstrapQuery = new NeutralQuery(0);
        bootstrapQuery.addCriteria(new NeutralCriteria("allowed_for_all_edorgs", "=", true));
        Iterable<Entity> bootstrapApps = repo.findAll("application", bootstrapQuery);

        for (Entity currentApp : bootstrapApps) {
            toReturn.add(currentApp.getEntityId());
        }
{'fraction_non_alphanumeric': 0.1002568417323532, 'fraction_numerical': 0.002125586750509255, 'mean_word_length': 3.0604099244875944, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '835181', 'n_tokens_mistral': 3203, 'n_tokens_neox': 3059, 'n_words': 836}