/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
Java | 347 lines | 252 code | 60 blank | 35 comment | 19 complexity | 43b4d4661b80d465112910441dad377d MD5 | raw file
- /*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
- * All rights reserved.
- *
- * 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 version 2 of the License.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- package org.rhq.enterprise.gui.coregui.client.admin.users;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import com.google.gwt.user.client.rpc.AsyncCallback;
- import com.smartgwt.client.data.DSRequest;
- import com.smartgwt.client.data.DSResponse;
- import com.smartgwt.client.data.DataSourceField;
- import com.smartgwt.client.data.Record;
- import com.smartgwt.client.data.fields.DataSourceIntegerField;
- import com.smartgwt.client.data.fields.DataSourcePasswordField;
- import com.smartgwt.client.data.fields.DataSourceTextField;
- import com.smartgwt.client.types.FieldType;
- import com.smartgwt.client.widgets.form.validator.LengthRangeValidator;
- import com.smartgwt.client.widgets.form.validator.MatchesFieldValidator;
- import com.smartgwt.client.widgets.form.validator.RegExpValidator;
- import com.smartgwt.client.widgets.grid.ListGridRecord;
- import org.rhq.core.domain.auth.Subject;
- import org.rhq.core.domain.criteria.SubjectCriteria;
- import org.rhq.core.domain.util.PageList;
- import org.rhq.enterprise.gui.coregui.client.admin.roles.RolesDataSource;
- import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
- import org.rhq.enterprise.gui.coregui.client.gwt.SubjectGWTServiceAsync;
- import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
- /**
- * A DataSource for RHQ {@link Subject user}s.
- *
- * @author Greg Hinkle
- * @author Ian Springer
- */
- public class UsersDataSource extends RPCDataSource<Subject, SubjectCriteria> {
- private static UsersDataSource INSTANCE;
- private static final String EMAIL_ADDRESS_REGEXP = "^([a-zA-Z0-9_.\\-+])+@([a-zA-Z0-9\\-])+(\\.([a-zA-Z0-9\\-])+)*$";
- private static final String MASKED_PASSWORD_VALUE = "XXXXXXXX";
- public static abstract class Field {
- public static final String ID = "id";
- public static final String NAME = "name";
- public static final String FIRST_NAME = "firstName";
- public static final String LAST_NAME = "lastName";
- public static final String FACTIVE = "factive";
- public static final String FSYSTEM = "fsystem";
- public static final String DEPARTMENT = "department";
- public static final String PHONE_NUMBER = "phoneNumber";
- public static final String EMAIL_ADDRESS = "emailAddress";
- public static final String ROLES = "roles";
- // auth-related fields
- public static final String LDAP = "ldap";
- public static final String PASSWORD = "password";
- public static final String PASSWORD_VERIFY = "passwordVerify";
- }
- public static final int ID_OVERLORD = 1;
- public static final int ID_RHQADMIN = 2;
- private final SubjectGWTServiceAsync subjectService = GWTServiceLookup.getSubjectService();
- public static UsersDataSource getInstance() {
- if (INSTANCE == null) {
- INSTANCE = new UsersDataSource();
- }
- return INSTANCE;
- }
- public static boolean isSystemSubjectId(int subjectId) {
- return (subjectId == ID_OVERLORD || subjectId == ID_RHQADMIN);
- }
- public UsersDataSource() {
- List<DataSourceField> fields = addDataSourceFields();
- addFields(fields);
- }
- @Override
- protected List<DataSourceField> addDataSourceFields() {
- List<DataSourceField> fields = super.addDataSourceFields();
- DataSourceField idDataField = new DataSourceIntegerField(Field.ID, "ID");
- idDataField.setPrimaryKey(true);
- idDataField.setCanEdit(false);
- fields.add(idDataField);
- DataSourceTextField usernameField = createTextField(Field.NAME, MSG.dataSource_users_field_name(), 3, 100, true);
- // Don't allow characters that could be used in HTML intended for an XSS attack.
- RegExpValidator regExpValidator = new RegExpValidator("[^&<]*");
- usernameField.setValidators(regExpValidator);
- fields.add(usernameField);
- DataSourceTextField ldapField = createBooleanField(Field.LDAP, MSG.dataSource_users_field_ldap(), true);
- ldapField.setCanEdit(false); // read-only
- fields.add(ldapField);
- DataSourcePasswordField passwordField = new DataSourcePasswordField(Field.PASSWORD,
- MSG.common_title_password(), 100, true);
- LengthRangeValidator passwordValidator = new LengthRangeValidator();
- passwordValidator.setMin(6);
- passwordValidator.setMax(100);
- passwordField.setValidators(passwordValidator);
- fields.add(passwordField);
- DataSourcePasswordField passwordVerifyField = new DataSourcePasswordField(Field.PASSWORD_VERIFY,
- MSG.dataSource_users_field_passwordVerify(), 100, true);
- MatchesFieldValidator passwordsEqualValidator = new MatchesFieldValidator();
- passwordsEqualValidator.setOtherField(Field.PASSWORD);
- passwordsEqualValidator.setErrorMessage(MSG.dataSource_users_passwordsDoNotMatch());
- passwordVerifyField.setValidators(passwordsEqualValidator);
- fields.add(passwordVerifyField);
- DataSourceTextField firstNameField = createTextField(Field.FIRST_NAME, MSG.dataSource_users_field_firstName(),
- null, 100, true);
- fields.add(firstNameField);
- DataSourceTextField lastNameField = createTextField(Field.LAST_NAME, MSG.dataSource_users_field_lastName(),
- null, 100, true);
- fields.add(lastNameField);
- DataSourceTextField emailAddressField = createTextField(Field.EMAIL_ADDRESS,
- MSG.dataSource_users_field_emailAddress(), null, 100, true);
- fields.add(emailAddressField);
- RegExpValidator emailAddressValidator = new RegExpValidator(EMAIL_ADDRESS_REGEXP);
- emailAddressValidator.setErrorMessage(MSG.dataSource_users_invalidEmailAddress());
- emailAddressField.setValidators(emailAddressValidator);
- DataSourceTextField phoneNumberField = createTextField(Field.PHONE_NUMBER,
- MSG.dataSource_users_field_phoneNumber(), null, 100, false);
- fields.add(phoneNumberField);
- DataSourceTextField departmentField = createTextField(Field.DEPARTMENT,
- MSG.dataSource_users_field_department(), null, 100, false);
- fields.add(departmentField);
- DataSourceTextField enabledField = createBooleanField(Field.FACTIVE, MSG.dataSource_users_field_factive(), true);
- fields.add(enabledField);
- DataSourceField rolesField = new DataSourceField(Field.ROLES, FieldType.ANY, "Roles");
- fields.add(rolesField);
- return fields;
- }
- @Override
- public void executeFetch(final DSRequest request, final DSResponse response, final SubjectCriteria criteria) {
- subjectService.findSubjectsByCriteria(criteria, new AsyncCallback<PageList<Subject>>() {
- public void onFailure(Throwable caught) {
- String message = "Failed to fetch user(s).";
- sendFailureResponse(request, response, message, caught);
- }
- public void onSuccess(final PageList<Subject> fetchedSubjects) {
- final PageList<Record> userRecordsPageList = new PageList<Record>(fetchedSubjects.getPageControl());
- userRecordsPageList.setTotalSize(fetchedSubjects.getTotalSize());
- userRecordsPageList.setUnbounded(fetchedSubjects.isUnbounded());
- final boolean[] failed = { false };
- for (int i = 0, fetchedSubjectsSize = fetchedSubjects.size(); i < fetchedSubjectsSize; i++) {
- if (failed[0]) {
- break;
- }
- final Subject fetchedSubject = fetchedSubjects.get(i);
- final String username = fetchedSubject.getName();
- subjectService.isUserWithPrincipal(username, new AsyncCallback<Boolean>() {
- public void onFailure(Throwable caught) {
- failed[0] = true;
- String message = "Failed to check if user [" + username + "] is an LDAP user.";
- sendFailureResponse(request, response, message, caught);
- }
- public void onSuccess(Boolean hasPrincipal) {
- boolean isLdap = (!hasPrincipal);
- Record userRecord = copyUserValues(fetchedSubject, isLdap);
- userRecordsPageList.add(userRecord);
- if (userRecordsPageList.size() == fetchedSubjects.size()) {
- sendSuccessResponseRecords(request, response, userRecordsPageList);
- }
- }
- });
- }
- }
- });
- }
- @Override
- protected void executeAdd(final Record recordToAdd, final DSRequest request, final DSResponse response) {
- final Subject newSubject = copyValues(recordToAdd);
- String password = recordToAdd.getAttribute(Field.PASSWORD);
- subjectService.createSubject(newSubject, password, new AsyncCallback<Subject>() {
- public void onFailure(Throwable caught) {
- // TODO: Throw more specific SLSB exceptions so we can set the right validation errors.
- String message = caught.getMessage();
- if (message != null && message.contains("javax.persistence.EntityExistsException")) {
- Map<String, String> errorMessages = new HashMap<String, String>();
- errorMessages.put(Field.NAME,
- MSG.view_adminUsers_failCreateUserWithExistingName(newSubject.getName()));
- sendValidationErrorResponse(request, response, errorMessages);
- } else {
- throw new RuntimeException(caught);
- }
- }
- public void onSuccess(final Subject createdSubject) {
- Record createdUserRecord = copyUserValues(createdSubject, false);
- sendSuccessResponse(request, response, createdUserRecord);
- }
- });
- }
- @Override
- protected void executeUpdate(final Record editedUserRecord, Record oldUserRecord, final DSRequest request,
- final DSResponse response) {
- Subject editedSubject = copyValues(editedUserRecord);
- final String username = editedSubject.getName();
- final String editedPassword = editedUserRecord.getAttributeAsString(Field.PASSWORD);
- boolean passwordWasEdited = !MASKED_PASSWORD_VALUE.equals(editedPassword);
- String newPassword = (passwordWasEdited) ? editedPassword : null;
- subjectService.updateSubject(editedSubject, newPassword, new AsyncCallback<Subject>() {
- public void onFailure(Throwable caught) {
- String message = "Failed to update user [" + username + "].";
- sendFailureResponse(request, response, message, caught);
- }
- public void onSuccess(final Subject updatedSubject) {
- sendSuccessResponse(request, response, editedUserRecord);
- }
- });
- }
- public Subject copyValues(Record from) {
- Subject to = new Subject();
- to.setId(from.getAttributeAsInt(Field.ID));
- to.setName(from.getAttributeAsString(Field.NAME));
- to.setFirstName(from.getAttributeAsString(Field.FIRST_NAME));
- to.setLastName(from.getAttributeAsString(Field.LAST_NAME));
- to.setFactive(Boolean.valueOf(from.getAttributeAsString(Field.FACTIVE)));
- to.setFsystem(Boolean.valueOf(from.getAttributeAsString(Field.FSYSTEM)));
- to.setDepartment(from.getAttributeAsString(Field.DEPARTMENT));
- to.setPhoneNumber(from.getAttributeAsString(Field.PHONE_NUMBER));
- to.setEmailAddress(from.getAttributeAsString(Field.EMAIL_ADDRESS));
- Record[] roleRecords = from.getAttributeAsRecordArray(Field.ROLES);
- to.setRoles(RolesDataSource.getInstance().buildDataObjects(roleRecords));
- return to;
- }
- public Record copyUserValues(Subject subject, boolean isLdap) {
- ListGridRecord targetRecord = copyValues(subject);
- targetRecord.setAttribute(Field.LDAP, isLdap);
- // Leave the password fields blank if username is null (i.e. it's a new user).
- if (subject.getName() != null) {
- targetRecord.setAttribute(Field.PASSWORD, MASKED_PASSWORD_VALUE);
- targetRecord.setAttribute(Field.PASSWORD_VERIFY, MASKED_PASSWORD_VALUE);
- }
- return targetRecord;
- }
- public ListGridRecord copyValues(Subject from) {
- return copyValues(from, true);
- }
- @Override
- public ListGridRecord copyValues(Subject from, boolean cascade) {
- ListGridRecord to = new ListGridRecord();
- to.setAttribute(Field.ID, from.getId());
- to.setAttribute(Field.NAME, from.getName());
- to.setAttribute(Field.FIRST_NAME, from.getFirstName());
- to.setAttribute(Field.LAST_NAME, from.getLastName());
- to.setAttribute(Field.FACTIVE, from.getFactive());
- to.setAttribute(Field.FSYSTEM, from.getFsystem());
- to.setAttribute(Field.DEPARTMENT, from.getDepartment());
- to.setAttribute(Field.PHONE_NUMBER, from.getPhoneNumber());
- to.setAttribute(Field.EMAIL_ADDRESS, from.getEmailAddress());
- if (cascade) {
- ListGridRecord[] roleRecords = RolesDataSource.getInstance().buildRecords(from.getRoles(), false);
- to.setAttribute(Field.ROLES, roleRecords);
- }
- return to;
- }
- @Override
- protected SubjectCriteria getFetchCriteria(DSRequest request) {
- SubjectCriteria criteria = new SubjectCriteria();
- // Filtering
- Integer subjectId = getFilter(request, Field.ID, Integer.class);
- criteria.addFilterId(subjectId);
- // Always filter out the overlord - mortal users need not know the overlord even exists.
- criteria.addFilterFsystem(false);
- // Fetching
- if (subjectId != null) {
- // If we're fetching a single Subject, then fetch the related Set of Roles.
- criteria.fetchRoles(true);
- }
- // TODO: For the list view, use a composite object that will pull the role
- // count across the wire. this count will not require permission checks at all.
- return criteria;
- }
- @Override
- protected String getSortFieldForColumn(String columnName) {
- // this is a calculated field, can't perform server-side sort
- if (Field.LDAP.equals(columnName)) {
- return null;
- }
- return super.getSortFieldForColumn(columnName);
- }
- }