/* * Copyright (C) 2012 Jan Pokorsky * * 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 cz.cas.lib.proarc.webapp.server.rest; import cz.cas.lib.proarc.common.user.Group; import cz.cas.lib.proarc.common.user.Permission; import cz.cas.lib.proarc.common.user.Permissions; import cz.cas.lib.proarc.common.user.UserManager; import cz.cas.lib.proarc.common.user.UserProfile; import cz.cas.lib.proarc.common.user.UserUtil; import cz.cas.lib.proarc.webapp.shared.rest.UserResourceApi; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.logging.Logger; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; /** * * @author Jan Pokorsky */ @Path(UserResourceApi.PATH) public final class UserResource { private static final Logger LOG = Logger.getLogger(UserResource.class.getName()); private final UserManager userManager; private final SessionContext session; public UserResource( @Context HttpServletRequest httpRequest, @Context SecurityContext securityCtx ) { this.session = SessionContext.from(httpRequest); this.userManager = UserUtil.getDefaultManger(); } @GET @Produces({MediaType.APPLICATION_JSON}) public SmartGwtResponse<UserProfile> find( @QueryParam(UserResourceApi.USER_ID) Integer userId, @QueryParam(UserResourceApi.USER_NAME) String userName, @QueryParam(UserResourceApi.USER_WHOAMI_PARAM) Boolean whoAmI ) { if (whoAmI != null && whoAmI) { userId = null; userName = session.getUser().getUserName(); } if (userId != null) { UserProfile found = userManager.find(userId); return new SmartGwtResponse<UserProfile>(found); } else if (userName != null && !userName.isEmpty()) { UserProfile found = userManager.find(userName); return new SmartGwtResponse<UserProfile>(found); } List<UserProfile> findAll = userManager.findAll(); return new SmartGwtResponse<UserProfile>(findAll); } @POST @Produces({MediaType.APPLICATION_JSON}) public SmartGwtResponse<UserProfile> add( @FormParam(UserResourceApi.USER_NAME) String userName, @FormParam(UserResourceApi.USER_PASSWORD) String passwd, @FormParam(UserResourceApi.USER_SURNAME) String surname, @FormParam(UserResourceApi.USER_FORENAME) String forename, @FormParam(UserResourceApi.USER_EMAIL) String email ) { checkAccess(session.getUser(), Permissions.ADMIN, Permissions.USERS_CREATE); if (userName == null) { return SmartGwtResponse.<UserProfile>asError() .error(UserResourceApi.USER_NAME, "missing") .build(); } UserProfile found = userManager.find(userName); if (found != null) { return SmartGwtResponse.<UserProfile>asError() .error(UserResourceApi.USER_NAME, "already exists") .build(); } UserProfile newProfile = new UserProfile(); newProfile.setEmail(email); newProfile.setForename(forename); newProfile.setSurname(surname); newProfile.setUserName(userName); newProfile.setUserPassword(passwd); newProfile = userManager.add(newProfile, Collections.<Group>emptyList(), session.getUser().getUserName(), session.asFedoraLog()); return new SmartGwtResponse<UserProfile>(newProfile); } @PUT @Produces({MediaType.APPLICATION_JSON}) public SmartGwtResponse<UserProfile> update( @FormParam(UserResourceApi.USER_ID) Integer userId, @FormParam(UserResourceApi.USER_PASSWORD) String passwd, @FormParam(UserResourceApi.USER_SURNAME) String surname, @FormParam(UserResourceApi.USER_FORENAME) String forename, @FormParam(UserResourceApi.USER_EMAIL) String email ) { UserProfile sessionUser = session.getUser(); // check for admin or the same user UserProfile update = userId == null ? null : userManager.find(userId); boolean fullUpdate; if (update != null && update.getUserName().equals(sessionUser.getUserName())) { Set<Permission> grants = checkAccess(sessionUser, (Permission) null); // fullUpdate = grants.contains(Permissions.ADMIN); fullUpdate = true; } else { checkAccess(sessionUser, Permissions.ADMIN); fullUpdate = true; } if (update == null) { return SmartGwtResponse.<UserProfile>asError() .error(UserResourceApi.USER_ID, "not found").build(); } if (passwd != null && update.getRemoteType() == null) { update.setUserPassword(passwd); } if (fullUpdate) { update.setEmail(email); update.setForename(forename); if (surname == null || surname.isEmpty()) { return SmartGwtResponse.<UserProfile>asError() .error(UserResourceApi.USER_SURNAME, "Required!").build(); } update.setSurname(surname); } userManager.update(update, sessionUser.getUserName(), session.asFedoraLog()); return new SmartGwtResponse<UserProfile>(update); } @Path("permissions") @GET @Produces({MediaType.APPLICATION_JSON}) public SmartGwtResponse<Permission> findPermissions( @QueryParam("userId") Integer userId ) { List<Permission> result = Collections.emptyList(); if (userId == null) { userId = session.getUser().getId(); } if (userId != null) { Set<Permission> permissions = userManager.findUserPermissions(userId); result = new ArrayList<Permission>(permissions); } return new SmartGwtResponse<Permission>(result); } Set<Permission> checkAccess(UserProfile user, Permission... permissions) { if (user != null) { Set<Permission> grants = userManager.findUserPermissions(user.getId()); for (Permission permission : permissions) { if (permission == null || grants.contains(permission)) { return grants; } } } throw new WebApplicationException(Response.Status.FORBIDDEN); } }