de.blizzy.documentr.access.UserStore.java Source code

Java tutorial

Introduction

Here is the source code for de.blizzy.documentr.access.UserStore.java

Source

/*
documentr - Edit, maintain, and present software documentation on the web.
Copyright (C) 2012-2013 Maik Schreiber
    
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/>.
*/
package de.blizzy.documentr.access;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.PersonIdent;
import org.gitective.core.BlobUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Closeables;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.StringMap;
import com.google.gson.reflect.TypeToken;

import de.blizzy.documentr.access.GrantedAuthorityTarget.Type;
import de.blizzy.documentr.repository.GlobalRepositoryManager;
import de.blizzy.documentr.repository.ILockedRepository;
import de.blizzy.documentr.repository.RepositoryUtil;

/** Manages storage of user account data. */
@Component
@Slf4j
public class UserStore {
    /** The login name of the anonymous user. */
    public static final String ANONYMOUS_USER_LOGIN_NAME = "_anonymous"; //$NON-NLS-1$

    private static final String REPOSITORY_NAME = "_users"; //$NON-NLS-1$
    private static final String USER_SUFFIX = ".user"; //$NON-NLS-1$
    private static final String ROLE_SUFFIX = ".role"; //$NON-NLS-1$
    private static final String AUTHORITIES_SUFFIX = ".authorities"; //$NON-NLS-1$

    @Autowired
    private GlobalRepositoryManager globalRepositoryManager;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostConstruct
    public void init() throws IOException, GitAPIException {
        String passwordHash = passwordEncoder.encodePassword("admin", "admin"); //$NON-NLS-1$ //$NON-NLS-2$
        User adminUser = new User("admin", passwordHash, "admin@example.com", false); //$NON-NLS-1$ //$NON-NLS-2$

        ILockedRepository repo = null;
        boolean created = false;
        try {
            repo = globalRepositoryManager.createProjectCentralRepository(REPOSITORY_NAME, false, adminUser);
            created = true;
        } catch (IllegalStateException e) {
            // okay
        } finally {
            Closeables.closeQuietly(repo);
        }

        if (created) {
            createInitialAdmin(adminUser);
            createInitialRoles(adminUser);
        }
    }

    private void createInitialAdmin(User adminUser) throws IOException {
        saveUser(adminUser, adminUser);
    }

    private void createInitialRoles(User adminUser) throws IOException {
        saveRole(new Role("Administrator", EnumSet.of(Permission.ADMIN)), adminUser); //$NON-NLS-1$
        saveRole(new Role("Editor", EnumSet.of(Permission.EDIT_BRANCH, Permission.EDIT_PAGE)), adminUser); //$NON-NLS-1$
        saveRole(new Role("Reader", EnumSet.of(Permission.VIEW)), adminUser); //$NON-NLS-1$

        Set<RoleGrantedAuthority> authorities = Collections
                .singleton(new RoleGrantedAuthority(GrantedAuthorityTarget.APPLICATION, "Administrator")); //$NON-NLS-1$
        saveUserAuthorities(adminUser.getLoginName(), authorities, adminUser);

        authorities = Collections.singleton(new RoleGrantedAuthority(GrantedAuthorityTarget.APPLICATION, "Reader")); //$NON-NLS-1$
        saveUserAuthorities(ANONYMOUS_USER_LOGIN_NAME, authorities, adminUser);
    }

    /**
     * Saves a user.
     *
     * @param user the user to save
     * @param currentUser the user performing the save operation
     */
    public void saveUser(User user, User currentUser) throws IOException {
        Assert.notNull(user);
        Assert.notNull(currentUser);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            Map<String, Object> userMap = new HashMap<String, Object>();
            userMap.put("loginName", user.getLoginName()); //$NON-NLS-1$
            userMap.put("password", user.getPassword()); //$NON-NLS-1$
            userMap.put("email", user.getEmail()); //$NON-NLS-1$
            userMap.put("disabled", Boolean.valueOf(user.isDisabled())); //$NON-NLS-1$
            if (!user.getOpenIds().isEmpty()) {
                userMap.put("openIds", user.getOpenIds()); //$NON-NLS-1$
            }

            Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
            String json = gson.toJson(userMap);
            File workingDir = RepositoryUtil.getWorkingDir(repo.r());
            File workingFile = new File(workingDir, user.getLoginName() + USER_SUFFIX);
            FileUtils.write(workingFile, json, Charsets.UTF_8);

            Git git = Git.wrap(repo.r());
            git.add().addFilepattern(user.getLoginName() + USER_SUFFIX).call();
            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident).setMessage(user.getLoginName()).call();
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    /**
     * Returns the user that has the specified login name.
     *
     * @throws UserNotFoundException when the user could not be found
     */
    public User getUser(String loginName) throws IOException {
        Assert.hasLength(loginName);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            String json = BlobUtils.getHeadContent(repo.r(), loginName + USER_SUFFIX);
            if (json == null) {
                throw new UserNotFoundException(loginName);
            }

            return getUser(loginName, json);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    private User getUser(String loginName, String json) {
        Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        Map<String, Object> userMap = gson.fromJson(json, new TypeToken<Map<String, Object>>() {
        }.getType());
        String password = (String) userMap.get("password"); //$NON-NLS-1$
        String email = (String) userMap.get("email"); //$NON-NLS-1$
        boolean disabled = ((Boolean) userMap.get("disabled")).booleanValue(); //$NON-NLS-1$
        @SuppressWarnings("unchecked")
        List<StringMap<String>> openIds = (List<StringMap<String>>) userMap.get("openIds"); //$NON-NLS-1$
        if (openIds == null) {
            openIds = Lists.newArrayList();
        }
        User user = new User(loginName, password, email, disabled);
        for (StringMap<String> map : openIds) {
            OpenId openId = new OpenId(map.get("delegateId"), map.get("realId")); //$NON-NLS-1$ //$NON-NLS-2$
            user.addOpenId(openId);
        }
        return user;
    }

    /** Returns all known user login names. */
    public List<String> listUsers() throws IOException {
        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            return listUsers(repo);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    private List<String> listUsers(ILockedRepository repo) {
        File workingDir = RepositoryUtil.getWorkingDir(repo.r());
        FileFilter filter = new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isFile() && file.getName().endsWith(USER_SUFFIX);
            }
        };
        List<File> files = Lists.newArrayList(workingDir.listFiles(filter));
        Function<File, String> function = new Function<File, String>() {
            @Override
            public String apply(File file) {
                return StringUtils.substringBeforeLast(file.getName(), USER_SUFFIX);
            }
        };
        List<String> users = Lists.newArrayList(Lists.transform(files, function));
        Collections.sort(users);
        return users;
    }

    /**
     * Saves a role.
     *
     * @param role the role to save
     * @param currentUser the user performing the save operation
     */
    public void saveRole(Role role, User currentUser) throws IOException {
        Assert.notNull(role);
        Assert.notNull(currentUser);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);

            Map<String, Object> roleMap = new HashMap<String, Object>();
            roleMap.put("name", role.getName()); //$NON-NLS-1$
            Set<String> permissions = Sets.newHashSet();
            for (Permission permission : role.getPermissions()) {
                permissions.add(permission.name());
            }
            roleMap.put("permissions", permissions); //$NON-NLS-1$

            Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
            String json = gson.toJson(roleMap);
            File workingDir = RepositoryUtil.getWorkingDir(repo.r());
            File workingFile = new File(workingDir, role.getName() + ROLE_SUFFIX);
            FileUtils.write(workingFile, json, Charsets.UTF_8);

            Git git = Git.wrap(repo.r());
            git.add().addFilepattern(role.getName() + ROLE_SUFFIX).call();
            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident).setMessage(role.getName()).call();
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    /** Returns all known role names. */
    public List<String> listRoles() throws IOException {
        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            File workingDir = RepositoryUtil.getWorkingDir(repo.r());
            FileFilter filter = new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return file.isFile() && file.getName().endsWith(ROLE_SUFFIX);
                }
            };
            List<File> files = Lists.newArrayList(workingDir.listFiles(filter));
            Function<File, String> function = new Function<File, String>() {
                @Override
                public String apply(File file) {
                    return StringUtils.substringBeforeLast(file.getName(), ROLE_SUFFIX);
                }
            };
            List<String> users = Lists.newArrayList(Lists.transform(files, function));
            Collections.sort(users);
            return users;
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    /**
     * Returns the role that has the specified name.
     *
     * @throws RoleNotFoundException when the role could not be found
     */
    public Role getRole(String roleName) throws IOException {
        Assert.hasLength(roleName);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            String json = BlobUtils.getHeadContent(repo.r(), roleName + ROLE_SUFFIX);
            if (json == null) {
                throw new RoleNotFoundException(roleName);
            }

            Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
            Map<String, Object> roleMap = gson.fromJson(json, new TypeToken<Map<String, Object>>() {
            }.getType());
            @SuppressWarnings("unchecked")
            Collection<String> permissions = (Collection<String>) roleMap.get("permissions"); //$NON-NLS-1$
            EnumSet<Permission> rolePermissions = EnumSet.noneOf(Permission.class);
            for (String permission : permissions) {
                rolePermissions.add(Permission.valueOf(permission));
            }
            Role role = new Role(roleName, rolePermissions);
            return role;
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    /**
     * Saves a user's authorities
     *
     * @param loginName the login name of the user whose authorities are to be saved
     * @param authorities the user's authorities to be saved
     * @param currentUser the user performing the save operation
     *
     * @throws UserNotFoundException when the user does not exist
     */
    public void saveUserAuthorities(String loginName, Set<RoleGrantedAuthority> authorities, User currentUser)
            throws IOException {

        Assert.hasLength(loginName);
        Assert.notNull(authorities);
        Assert.notNull(currentUser);
        if (!loginName.equals(ANONYMOUS_USER_LOGIN_NAME)) {
            // check that user exists by trying to load it
            getUser(loginName);
        }

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            saveUserAuthorities(loginName, authorities, repo, currentUser, true);
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    private void saveUserAuthorities(String loginName, Set<RoleGrantedAuthority> authorities,
            ILockedRepository repo, User currentUser, boolean commit) throws IOException, GitAPIException {

        Map<String, Set<String>> authoritiesMap = new HashMap<String, Set<String>>();
        for (RoleGrantedAuthority rga : authorities) {
            GrantedAuthorityTarget target = rga.getTarget();
            String targetStr = target.getType().name() + ":" + target.getTargetId(); //$NON-NLS-1$
            Set<String> roleNames = authoritiesMap.get(targetStr);
            if (roleNames == null) {
                roleNames = Sets.newHashSet();
                authoritiesMap.put(targetStr, roleNames);
            }
            roleNames.add(rga.getRoleName());
        }

        Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        String json = gson.toJson(authoritiesMap);
        File workingDir = RepositoryUtil.getWorkingDir(repo.r());
        File workingFile = new File(workingDir, loginName + AUTHORITIES_SUFFIX);
        FileUtils.write(workingFile, json, Charsets.UTF_8);

        Git git = Git.wrap(repo.r());
        git.add().addFilepattern(loginName + AUTHORITIES_SUFFIX).call();
        if (commit) {
            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident).setMessage(loginName).call();
        }
    }

    /**
     * Returns a user's authorities.
     *
     * @param loginName the login name of the user
     *
     * @throws UserNotFoundException when the user does not exist
     */
    public List<RoleGrantedAuthority> getUserAuthorities(String loginName) throws IOException {
        Assert.hasLength(loginName);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            return getUserAuthorities(loginName, repo);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    private List<RoleGrantedAuthority> getUserAuthorities(String loginName, ILockedRepository repo) {
        String json = BlobUtils.getHeadContent(repo.r(), loginName + AUTHORITIES_SUFFIX);
        if (json == null) {
            throw new UserNotFoundException(loginName);
        }

        Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        Map<String, Set<String>> authoritiesMap = gson.fromJson(json, new TypeToken<Map<String, Set<String>>>() {
        }.getType());
        List<RoleGrantedAuthority> authorities = Lists.newArrayList();
        for (Map.Entry<String, Set<String>> entry : authoritiesMap.entrySet()) {
            String targetStr = entry.getKey();
            Type type = Type.valueOf(StringUtils.substringBefore(targetStr, ":")); //$NON-NLS-1$
            String targetId = StringUtils.substringAfter(targetStr, ":"); //$NON-NLS-1$
            for (String roleName : entry.getValue()) {
                authorities.add(new RoleGrantedAuthority(new GrantedAuthorityTarget(targetId, type), roleName));
            }
        }

        Collections.sort(authorities, new RoleGrantedAuthorityComparator());

        return authorities;
    }

    /**
     * Returns the user that has an OpenID whose real ID is equal to the specified OpenID.
     *
     * @throws UserNotFoundException when the user could not be found
     */
    public User getUserByOpenId(String openId) throws IOException {
        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            File workingDir = RepositoryUtil.getWorkingDir(repo.r());
            FileFilter filter = new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return file.isFile() && file.getName().endsWith(USER_SUFFIX);
                }
            };
            for (File file : workingDir.listFiles(filter)) {
                String loginName = StringUtils.substringBeforeLast(file.getName(), USER_SUFFIX);
                String json = FileUtils.readFileToString(file, Charsets.UTF_8);
                User user = getUser(loginName, json);
                for (OpenId id : user.getOpenIds()) {
                    if (id.getRealId().equals(openId)) {
                        return user;
                    }
                }
            }

            throw new OpenIdNotFoundException(openId);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    /**
     * Converts a {@link RoleGrantedAuthority} to a set of {@link PermissionGrantedAuthority}.
     * This method will return an empty set if the role specified by the RoleGrantedAuthority does not exist
     * (rather than throwing a {@link RoleNotFoundException}.)
     */
    Set<PermissionGrantedAuthority> toPermissionGrantedAuthorities(RoleGrantedAuthority rga) throws IOException {
        Set<PermissionGrantedAuthority> result = Sets.newHashSet();
        try {
            Role role = getRole(rga.getRoleName());
            GrantedAuthorityTarget target = rga.getTarget();
            for (Permission permission : role.getPermissions()) {
                result.add(new PermissionGrantedAuthority(target, permission));
            }
        } catch (RoleNotFoundException e) {
            // role might have been deleted
        }
        return result;
    }

    public void deleteUser(String loginName, User currentUser) throws IOException {
        Assert.hasLength(loginName);
        Assert.notNull(currentUser);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            Git git = Git.wrap(repo.r());
            git.rm().addFilepattern(loginName + USER_SUFFIX).call();
            git.rm().addFilepattern(loginName + AUTHORITIES_SUFFIX).call();
            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident).setMessage("delete user " + loginName) //$NON-NLS-1$
                    .call();
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    public void renameUser(String loginName, String newLoginName, User currentUser) throws IOException {
        Assert.hasLength(loginName);
        Assert.hasLength(newLoginName);
        Assert.notNull(currentUser);
        // check that user exists by trying to load it
        getUser(loginName);
        // check that new user does not exist by trying to load it
        try {
            getUser(newLoginName);
            throw new IllegalArgumentException("user already exists: " + newLoginName); //$NON-NLS-1$
        } catch (UserNotFoundException e) {
            // okay
        }

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);

            File workingDir = RepositoryUtil.getWorkingDir(repo.r());
            File file = new File(workingDir, loginName + USER_SUFFIX);
            File newFile = new File(workingDir, newLoginName + USER_SUFFIX);
            FileUtils.copyFile(file, newFile);
            file = new File(workingDir, loginName + AUTHORITIES_SUFFIX);
            newFile = new File(workingDir, newLoginName + AUTHORITIES_SUFFIX);
            FileUtils.copyFile(file, newFile);
            Git git = Git.wrap(repo.r());
            git.rm().addFilepattern(loginName + USER_SUFFIX).call();
            git.rm().addFilepattern(loginName + AUTHORITIES_SUFFIX).call();
            git.add().addFilepattern(newLoginName + USER_SUFFIX).call();
            git.add().addFilepattern(newLoginName + AUTHORITIES_SUFFIX).call();
            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident)
                    .setMessage("rename user " + loginName + " to " + newLoginName) //$NON-NLS-1$ //$NON-NLS-2$
                    .call();
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    public void renameRole(String roleName, String newRoleName, User currentUser) throws IOException {
        Assert.hasLength(roleName);
        Assert.hasLength(newRoleName);
        Assert.notNull(currentUser);
        // check that role exists by trying to load it
        getRole(roleName);
        // check that new role does not exist by trying to load it
        try {
            getRole(newRoleName);
            throw new IllegalArgumentException("role already exists: " + newRoleName); //$NON-NLS-1$
        } catch (RoleNotFoundException e) {
            // okay
        }

        log.info("renaming role: {} -> {}", roleName, newRoleName); //$NON-NLS-1$

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);

            File workingDir = RepositoryUtil.getWorkingDir(repo.r());

            File file = new File(workingDir, roleName + ROLE_SUFFIX);
            File newFile = new File(workingDir, newRoleName + ROLE_SUFFIX);
            FileUtils.copyFile(file, newFile);
            Git git = Git.wrap(repo.r());
            git.rm().addFilepattern(roleName + ROLE_SUFFIX).call();
            git.add().addFilepattern(newRoleName + ROLE_SUFFIX).call();

            List<String> users = listUsers(repo);
            users.add(ANONYMOUS_USER_LOGIN_NAME);
            for (String user : users) {
                List<RoleGrantedAuthority> authorities = getUserAuthorities(user, repo);
                Set<RoleGrantedAuthority> newAuthorities = Sets.newHashSet();
                for (Iterator<RoleGrantedAuthority> iter = authorities.iterator(); iter.hasNext();) {
                    RoleGrantedAuthority rga = iter.next();
                    if (rga.getRoleName().equals(roleName)) {
                        RoleGrantedAuthority newRga = new RoleGrantedAuthority(rga.getTarget(), newRoleName);
                        newAuthorities.add(newRga);
                        iter.remove();
                    }
                }
                if (!newAuthorities.isEmpty()) {
                    authorities.addAll(newAuthorities);
                    saveUserAuthorities(user, Sets.newHashSet(authorities), repo, currentUser, false);
                }
            }

            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident)
                    .setMessage("rename role " + roleName + " to " + newRoleName) //$NON-NLS-1$ //$NON-NLS-2$
                    .call();
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }

    public void deleteRole(String roleName, User currentUser) throws IOException {
        Assert.hasLength(roleName);
        Assert.notNull(currentUser);
        // check that role exists by trying to load it
        getRole(roleName);

        ILockedRepository repo = null;
        try {
            repo = globalRepositoryManager.getProjectCentralRepository(REPOSITORY_NAME, false);
            Git git = Git.wrap(repo.r());

            git.rm().addFilepattern(roleName + ROLE_SUFFIX).call();

            // remove role from all users
            List<String> users = listUsers(repo);
            users.add(ANONYMOUS_USER_LOGIN_NAME);
            for (String user : users) {
                List<RoleGrantedAuthority> authorities = getUserAuthorities(user, repo);
                boolean changed = false;
                for (Iterator<RoleGrantedAuthority> iter = authorities.iterator(); iter.hasNext();) {
                    RoleGrantedAuthority rga = iter.next();
                    if (rga.getRoleName().equals(roleName)) {
                        iter.remove();
                        changed = true;
                    }
                }
                if (changed) {
                    saveUserAuthorities(user, Sets.newHashSet(authorities), repo, currentUser, false);
                }
            }

            PersonIdent ident = new PersonIdent(currentUser.getLoginName(), currentUser.getEmail());
            git.commit().setAuthor(ident).setCommitter(ident).setMessage("delete role " + roleName) //$NON-NLS-1$
                    .call();
        } catch (GitAPIException e) {
            throw new IOException(e);
        } finally {
            Closeables.closeQuietly(repo);
        }
    }
}