/* * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.server.rest.model.user; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import jetbrains.buildServer.server.rest.ApiUrlBuilder; import jetbrains.buildServer.server.rest.data.DataProvider; import jetbrains.buildServer.server.rest.data.DataUpdater; import jetbrains.buildServer.server.rest.errors.AuthorizationFailedException; import jetbrains.buildServer.server.rest.errors.BadRequestException; import jetbrains.buildServer.server.rest.model.Properties; import jetbrains.buildServer.server.rest.model.Util; import jetbrains.buildServer.server.rest.model.group.Groups; import jetbrains.buildServer.serverSide.TeamCityProperties; import jetbrains.buildServer.serverSide.auth.AuthorityHolder; import jetbrains.buildServer.serverSide.auth.Permission; import jetbrains.buildServer.serverSide.auth.SecurityContext; import jetbrains.buildServer.serverSide.impl.auth.ServerAuthUtil; import jetbrains.buildServer.users.PropertyKey; import jetbrains.buildServer.users.SUser; import jetbrains.buildServer.util.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * User: Yegor Yarko * Date: 12.04.2009 */ @XmlRootElement(name = "user") public class User { private SUser myUser; private ApiUrlBuilder myApiUrlBuilder; private DataProvider myDataProvider; public User() { } public User(jetbrains.buildServer.users.SUser user, @NotNull final ApiUrlBuilder apiUrlBuilder, @NotNull final DataProvider dataProvider) { this.myUser = user; myApiUrlBuilder = apiUrlBuilder; myDataProvider = dataProvider; } private static boolean isCanViewUserDetails(@Nullable final SUser user, @NotNull final DataProvider dataProvider) { try { SUser currentUserUser = dataProvider.getCurrentUser(); if (currentUserUser != null && user != null && currentUserUser.getId() == user.getId()) { return true; } final AuthorityHolder currentUser = dataProvider.getServer().getSingletonService(SecurityContext.class).getAuthorityHolder(); if (!currentUser.isPermissionGrantedGlobally(Permission.VIEW_USER_PROFILE) && !currentUser.isPermissionGrantedGlobally(Permission.CHANGE_USER)){ return false; } if (TeamCityProperties.getBoolean("rest.beans.user.checkPermissions.limitViewUserProfileToListableUsersOnly")) { // related to TW-51644 // see AdminEditUserController for related code if (user != null) { return ServerAuthUtil.canViewUser(currentUser, user); } return currentUser.isPermissionGrantedGlobally(Permission.VIEW_ALL_USERS) || currentUser.isPermissionGrantedGlobally(Permission.CHANGE_USER); } } catch (RuntimeException e) { return false; } return true; } @XmlAttribute public Long getId() { return myUser.getId(); } @XmlAttribute public String getName() { return myUser.getName(); } @XmlAttribute public String getUsername() { return myUser.getUsername(); } @XmlAttribute public String getLastLogin() { if (!isCanViewUserDetails(myUser, myDataProvider)) { return null; } Date lastLoginTimestamp = myUser.getLastLoginTimestamp(); if (lastLoginTimestamp != null) { return Util.formatTime(lastLoginTimestamp); } return null; } @XmlAttribute public String getEmail() { if (!isCanViewUserDetails(myUser, myDataProvider)) { return null; } return myUser.getEmail(); } @XmlElement(name = "roles") public RoleAssignments getRoles() { if (!isCanViewUserDetails(myUser, myDataProvider)) { return null; } return new RoleAssignments(myUser.getRoles(), myUser, myApiUrlBuilder); } @XmlElement(name = "groups") public Groups getGroups() { if (!isCanViewUserDetails(myUser, myDataProvider)) { return null; } return new Groups(myUser.getUserGroups(), myApiUrlBuilder); } @XmlAttribute public String getRealm() { return myUser.getRealm(); } @XmlElement(name = "properties") public Properties getProperties() { if (!isCanViewUserDetails(myUser, myDataProvider)) { return null; } return new Properties(getUserProperties(myUser)); } public static Map getUserProperties(final SUser user) { Map convertedProperties = new HashMap(); for (Map.Entry prop : user.getProperties().entrySet()) { convertedProperties.put(prop.getKey().getKey(), prop.getValue()); } return convertedProperties; } public static String getFieldValue(@NotNull final SUser user, @Nullable final String name, @NotNull final DataProvider dataProvider) { if (StringUtil.isEmpty(name)) { throw new BadRequestException("Field name cannot be empty"); } if ("id".equals(name)) { return String.valueOf(user.getId()); } else if ("name".equals(name)) { return user.getName(); } else if ("username".equals(name)) { return user.getUsername(); } else if ("email".equals(name)) { if (!isCanViewUserDetails(user, dataProvider)) { throw new AuthorizationFailedException("No permission to view full detail of user with id \"" + user.getId() + "\""); } return user.getEmail(); } throw new BadRequestException("Unknown field '" + name + "'. Supported fields are: id, name, username, email"); } public static void setFieldValue(@NotNull final SUser user, @Nullable final String name, @NotNull final String value) { if (StringUtil.isEmpty(name)) { throw new BadRequestException("Field name cannot be empty"); } if ("username".equals(name)) { DataUpdater.updateUserCoreFields(user, value, null, null, null); return; } else if ("name".equals(name)) { DataUpdater.updateUserCoreFields(user, null, value, null, null); return; } else if ("email".equals(name)) { DataUpdater.updateUserCoreFields(user, null, null, value, null); return; } else if ("password".equals(name)) { DataUpdater.updateUserCoreFields(user, null, null, null, value); return; } throw new BadRequestException("Changing field '" + name + "' is not supported. Supported fields are: username, name, email, password"); } // These are necessary for allowing to submit the same class private String name; private String username; private String email; private String password; private RoleAssignments roles; private Groups groups; private Properties properties; public void setName(final String name) { this.name = name; } public void setUsername(final String username) { this.username = username; } public void setEmail(final String email) { this.email = email; } public void setPassword(final String password) { this.password = password; } public void setRoles(final RoleAssignments roles) { this.roles = roles; } public void setGroups(final Groups groups) { this.groups = groups; } public void setProperties(final Properties properties) { this.properties = properties; } public String getSubmittedName() { return name; } public String getSubmittedUsername() { return username; } public String getSubmittedEmail() { return email; } public String getSubmittedPassword() { return password; } public RoleAssignments getSubmittedRoles() { return roles; } public Groups getSubmittedGroups() { return groups; } public Properties getSubmittedProperties() { return properties; } }