/* * The MIT License (MIT) * * Copyright (c) 2014 Andreas Alanko, Emil Nilsson, Sony Mobile Communications AB. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.sonymobile.jenkins.plugins.gitlab.gitlabauth.acl; import com.sonymobile.gitlab.model.GitLabAccessLevel; import com.sonymobile.jenkins.plugins.gitlab.gitlabauth.acl.GitLabPermissionIdentity.IdentityType; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import hudson.security.Permission; import hudson.security.PermissionGroup; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.logging.Logger; /** * Used to store permission identities and their respective granted permissions. * * @author Andreas Alanko */ public class GitLabGrantedPermissions { /** Map of GitLab identities and their respective granted permissions. */ private Map<GitLabPermissionIdentity, List<Permission>> grantedPermissions; /** * Creates a TreeMap to store the identities and their respective granted permissions. */ public GitLabGrantedPermissions() { grantedPermissions = new TreeMap<GitLabPermissionIdentity, List<Permission>>(); } /** * Checks if the given identity has the given permission. * * @param identity the identity * @param permission the permission * @return true if the identity has permission */ public boolean isPermissionSet(GitLabPermissionIdentity identity, Permission permission) { if (identity != null && permission != null) { if (grantedPermissions.containsKey(identity)) { return grantedPermissions.get(identity).contains(permission); } } return false; } /** * Adds a permission for the given identity. * * @param identity the identity * @param permission the permission */ public void addPermission(GitLabPermissionIdentity identity, Permission permission) { if (identity != null && permission != null) { if (!grantedPermissions.containsKey(identity)) { grantedPermissions.put(identity, new ArrayList<Permission>()); } grantedPermissions.get(identity).add(permission); } } /** * Adds multiple permissions for a the given identity. * * @param identity the identity * @param permissions the permissions */ public void addPermissions(GitLabPermissionIdentity identity, Iterable<Permission> permissions) { for (final Permission permission : permissions) { addPermission(identity, permission); } } /** * Adds all permissions from a permission group for the given identity. * * @param identity the identity * @param permissionGroup the permission group */ public void addPermissionGroup(GitLabPermissionIdentity identity, PermissionGroup permissionGroup) { addPermissions(identity, permissionGroup.getPermissions()); } /** * Adds all permissions from multiple permission groups for the given identity. * * @param identity the identity * @param permissionGroups the permission groups */ public void addPermissionGroups(GitLabPermissionIdentity identity, Iterable<PermissionGroup> permissionGroups) { for (final PermissionGroup permissionGroup : permissionGroups) { addPermissionGroup(identity, permissionGroup); } } /** * Gets a list with the configured GitLabPermission identities for this object. * * The list will include all static Jenkins identities and if specified also all static GitLab identities. * * @param getGitLabIdentities if GitLab identities should be included * @return a list of GitLabPermissionIdentities */ public List<GitLabPermissionIdentity> getPermissionIdentities(boolean getGitLabIdentities) { List<GitLabPermissionIdentity> list = GitLabPermissionIdentity.getGlobalStaticPermissionIdentities(getGitLabIdentities); List<GitLabPermissionIdentity> grantedIdentities = new ArrayList<GitLabPermissionIdentity>(grantedPermissions.keySet()); for (GitLabPermissionIdentity pi : grantedIdentities) { if (!list.contains(pi) && (pi.type.equals(IdentityType.USER) || pi.type.equals(IdentityType.GROUP))) { list.add(pi); } } return list; } public List<GitLabPermissionIdentity> getGroupPermissionIdentities() { List<GitLabPermissionIdentity> list = new ArrayList<GitLabPermissionIdentity>(); for (GitLabPermissionIdentity identity : grantedPermissions.keySet()) { if (identity.type.equals(IdentityType.GROUP)) { list.add(identity); } } return list; } /** Converter class used to store and restore the internal state of this object to a config.xml file. */ public static class ConverterImpl implements Converter { /** The XML field name in the config.xml file. */ private static final String XML_FIELD_PERMISSION = "permission"; /** Logger for this class. */ private final transient Logger LOGGER = Logger.getLogger(GitLabGlobalACL.class.getName()); public boolean canConvert(Class clazz) { return clazz.equals(GitLabGrantedPermissions.class); } /** Used to write the internal data to the config.xml file. */ public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { GitLabGrantedPermissions grantedPermissions = (GitLabGrantedPermissions)value; for (GitLabPermissionIdentity pi : grantedPermissions.grantedPermissions.keySet()) { List<Permission> permissions = grantedPermissions.grantedPermissions.get(pi); for (int i = 0; i < permissions.size(); i++) { writer.startNode(XML_FIELD_PERMISSION); writer.setValue(pi.type + ":" + pi.id + ":" + permissions.get(i).getId()); writer.endNode(); } } } /** Used to parse data stored in the config.xml file. */ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { GitLabGrantedPermissions grantedPermissions = new GitLabGrantedPermissions(); while (reader.hasMoreChildren()) { reader.moveDown(); if (XML_FIELD_PERMISSION.equals(reader.getNodeName())) { String readerValue = reader.getValue(); String[] value = readerValue.split(":"); if (value.length == 3) { GitLabPermissionIdentity identity = null; IdentityType type = IdentityType.valueOf(value[0]); String id = value[1]; switch (type) { case GITLAB: identity = GitLabPermissionIdentity.getGitLabIdentityFromAccessLevel( GitLabAccessLevel.getAccessLevelWithName(id)); break; case JENKINS: identity = GitLabPermissionIdentity.getJenkinsIdentityFromAccessLevel( JenkinsAccessLevel.getAccessLevelWithName(id)); break; case GROUP: identity = GitLabPermissionIdentity.group(id); break; case USER: identity = GitLabPermissionIdentity.user(id); break; } Permission permission = Permission.fromId(value[2]); if (permission != null) { grantedPermissions.addPermission(identity, permission); } else { LOGGER.warning("Unknown permission id: " + value[2]); } } else { LOGGER.warning("Couldn't parse identity/permission: " + readerValue); } } reader.moveUp(); } return grantedPermissions; } } }