co.mitro.core.servlets.GetOrganizationState.java Source code

Java tutorial

Introduction

Here is the source code for co.mitro.core.servlets.GetOrganizationState.java

Source

/*******************************************************************************
 * Copyright (c) 2013, 2014 Lectorius, Inc.
 * Authors:
 * Vijay Pandurangan (vijayp@mitro.co)
 * Evan Jones (ej@mitro.co)
 * Adam Hilss (ahilss@mitro.co)
 *
 *
 *     This program 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 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program 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.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *     
 *     You can contact the authors at inbound@mitro.co.
 *******************************************************************************/
package co.mitro.core.servlets;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.servlet.annotation.WebServlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import co.mitro.core.accesscontrol.AuthenticatedDB;
import co.mitro.core.exceptions.MitroServletException;
import co.mitro.core.server.data.DBAcl;
import co.mitro.core.server.data.DBGroup;
import co.mitro.core.server.data.DBIdentity;
import co.mitro.core.server.data.RPC.GetOrganizationStateRequest;
import co.mitro.core.server.data.RPC.GetOrganizationStateResponse;
import co.mitro.core.server.data.RPC.ListMySecretsAndGroupKeysResponse.GroupInfo;
import co.mitro.core.server.data.RPC.ListMySecretsAndGroupKeysResponse.SecretToPath;
import co.mitro.core.server.data.RPC.MitroRPC;
import co.mitro.core.servlets.ListMySecretsAndGroupKeys.AdminAccess;
import co.mitro.core.servlets.ListMySecretsAndGroupKeys.IncludeAuditLogInfo;

import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

@WebServlet("/api/GetOrganizationState")
public class GetOrganizationState extends MitroServlet {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(GetOrganizationState.class);

    @Override
    protected MitroRPC processCommand(MitroRequestContext context)
            throws IOException, SQLException, MitroServletException {
        GetOrganizationStateRequest in = gson.fromJson(context.jsonRequest, GetOrganizationStateRequest.class);
        return doOperation(context, in.orgId);
    }

    public static GetOrganizationStateResponse doOperation(MitroRequestContext context, int orgId)
            throws MitroServletException, SQLException {
        Stopwatch stopwatch = Stopwatch.createStarted();
        GetOrganizationStateResponse out = new GetOrganizationStateResponse();

        @SuppressWarnings("deprecation")
        AuthenticatedDB userDb = AuthenticatedDB.deprecatedNew(context.manager, context.requestor);
        DBGroup org = userDb.getOrganizationAsMember(orgId);
        assert (null != org);

        Set<String> users = Sets.newHashSet();
        Set<Integer> groupIds = ListMySecretsAndGroupKeys.getGroupsUsersAndOrgsFromRawStatement(context, null,
                org.getId(), out.groups, out.organizations, null, users);

        // prevent users who are memebers of org groups but not members of the org from being returned as members.
        Set<String> orgMembers = DBIdentity.getUserNamesFromIds(context.manager,
                MutateOrganization.getMemberIdsAndPrivateGroupIdsForOrg(context.manager, org).keySet());
        out.members = Lists.newArrayList(Sets.intersection(orgMembers, users));

        Set<Integer> orgAdmins = Sets.newHashSet();
        org.putDirectUsersIntoSet(orgAdmins, DBAcl.adminAccess());
        out.admins = Lists.newArrayList(DBIdentity.getUserNamesFromIds(context.manager, orgAdmins));

        // all users get a list of THEIR secrets
        if (userDb.isOrganizationAdmin(orgId)) {
            // if user is admin: get list of secrets
            // TODO: audit log is super slow; this should move to its own API call?
            final IncludeAuditLogInfo GET_AUDIT = IncludeAuditLogInfo.NO_AUDIT_LOG_INFO;
            groupIds.add(org.getId());
            ListMySecretsAndGroupKeys.getSecretInfo(context, AdminAccess.FORCE_ACCESS_VIA_TOPLEVEL_GROUPS,
                    out.orgSecretsToPath, groupIds, null, GET_AUDIT);

            // any org secrets with no users, no hidden groups and only the org group are orphaned.
            out.orphanedSecretsToPath = Maps.newHashMap();
            for (Iterator<Entry<Integer, SecretToPath>> iter = out.orgSecretsToPath.entrySet().iterator(); iter
                    .hasNext();) {
                Entry<Integer, SecretToPath> entry = iter.next();
                SecretToPath stp = entry.getValue();
                if (stp.users.isEmpty() && stp.hiddenGroups.isEmpty() && stp.groups.size() == 1) {
                    // this is an orphaned secret
                    assert (stp.groups.get(0) == org.getId());
                    out.orphanedSecretsToPath.put(entry.getKey(), entry.getValue());
                    // remove orphaned secrets from regular org secrets
                    iter.remove();
                }
            }
        } else {
            // these variables are not filled; set to null so the caller doesn't rely on them
            out.orgSecretsToPath = null;
            out.orphanedSecretsToPath = null;
            out.organizations = null;

            // Remove private data from groups: membership; encrypted keys
            for (GroupInfo group : out.groups.values()) {
                group.users = null;
                group.encryptedPrivateKey = null;
            }
        }

        logger.info("{} elapsed: {} ms:", context.requestor, stopwatch.elapsed(TimeUnit.MILLISECONDS));
        return out;
    }
}