001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     dmetzler
018 */
019package org.nuxeo.ecm.restapi.server.jaxrs.usermanager;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import javax.ws.rs.DELETE;
025import javax.ws.rs.POST;
026import javax.ws.rs.core.Response;
027import javax.ws.rs.core.Response.Status;
028
029import org.nuxeo.ecm.core.api.NuxeoGroup;
030import org.nuxeo.ecm.core.api.NuxeoPrincipal;
031import org.nuxeo.ecm.directory.BaseSession;
032import org.nuxeo.ecm.platform.usermanager.UserManager;
033import org.nuxeo.ecm.webengine.model.WebObject;
034import org.nuxeo.ecm.webengine.model.exceptions.WebSecurityException;
035import org.nuxeo.ecm.webengine.model.impl.DefaultObject;
036import org.nuxeo.runtime.api.Framework;
037
038/**
039 * @since 5.7.3
040 */
041@WebObject(type = "userToGroup")
042public class UserToGroupObject extends DefaultObject {
043
044    private NuxeoGroup group;
045
046    private NuxeoPrincipal principal;
047
048    @Override
049    protected void initialize(Object... args) {
050        if (args.length != 2) {
051            throw new IllegalArgumentException("UserToGroup object takes two parameters");
052        }
053        principal = (NuxeoPrincipal) args[0];
054        group = (NuxeoGroup) args[1];
055    }
056
057    @POST
058    public Response doAddUserToGroup() {
059        UserManager um = Framework.getService(UserManager.class);
060        checkPrincipalCanAdministerGroupAndUser(um);
061        addUserToGroup(principal, group);
062        return Response.status(Status.CREATED).entity(um.getPrincipal(principal.getName())).build();
063    }
064
065    private void checkPrincipalCanAdministerGroupAndUser(UserManager um) {
066        NuxeoPrincipal currentPrincipal = getContext().getCoreSession().getPrincipal();
067        if (!currentPrincipal.isAdministrator()) {
068            if (!currentPrincipal.isMemberOf("powerusers") || !UserRootObject.isAPowerUserEditableUser(principal)
069                    || !GroupRootObject.isAPowerUserEditableGroup(group)) {
070                throw new WebSecurityException("Cannot edit user");
071            }
072        }
073
074    }
075
076    @DELETE
077    public Response doRemoveUserFromGroup() {
078        UserManager um = Framework.getService(UserManager.class);
079        checkPrincipalCanAdministerGroupAndUser(um);
080        removeUserFromGroup(principal, group);
081        return Response.ok(principal.getName()).build();
082    }
083
084    protected void addUserToGroup(NuxeoPrincipal principal, NuxeoGroup group) {
085        UserManager userManager = Framework.getService(UserManager.class);
086        if (!BaseSession.isReadOnlyEntry(principal.getModel())) {
087            // we can write to the principal
088            List<String> groups = principal.getGroups();
089            if (groups == null) {
090                groups = new ArrayList<>();
091            }
092            String groupName = group.getName();
093            if (!groups.contains(groupName)) {
094                groups.add(groupName);
095                principal.setGroups(groups);
096                userManager.updateUser(principal.getModel());
097            }
098        } else {
099            // principal is read-only, update through the group instead
100            List<String> users = group.getMemberUsers();
101            if (users == null) {
102                users = new ArrayList<>();
103            }
104            String userName = principal.getName();
105            if (!users.contains(userName)) {
106                users.add(userName);
107                group.setMemberUsers(users);
108                userManager.updateGroup(group.getModel());
109            }
110        }
111    }
112
113    protected void removeUserFromGroup(NuxeoPrincipal principal, NuxeoGroup group) {
114        UserManager userManager = Framework.getService(UserManager.class);
115        if (!BaseSession.isReadOnlyEntry(principal.getModel())) {
116            // we can write to the principal
117            List<String> groups = principal.getGroups();
118            if (groups == null) {
119                groups = new ArrayList<>();
120            }
121            String groupName = group.getName();
122            if (groups.contains(groupName)) {
123                groups.remove(groupName);
124                principal.setGroups(groups);
125                userManager.updateUser(principal.getModel());
126            }
127        } else {
128            // principal is read-only, update through the group instead
129            List<String> users = group.getMemberUsers();
130            if (users == null) {
131                users = new ArrayList<>();
132            }
133            String userName = principal.getName();
134            if (users.contains(userName)) {
135                users.remove(userName);
136                group.setMemberUsers(users);
137                userManager.updateGroup(group.getModel());
138            }
139        }
140    }
141
142}