You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2012/11/22 00:11:33 UTC

svn commit: r1412355 [2/2] - in /ace/trunk: build/ org.apache.ace.useradmin.ui.itest/ org.apache.ace.useradmin.ui.itest/conf/ org.apache.ace.useradmin.ui.itest/conf/org.apache.ace.connectionfactory/ org.apache.ace.useradmin.ui.itest/conf/org.apache.ace...

Added: ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/editor/impl/UserEditorImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/editor/impl/UserEditorImpl.java?rev=1412355&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/editor/impl/UserEditorImpl.java (added)
+++ ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/editor/impl/UserEditorImpl.java Wed Nov 21 23:11:26 2012
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ace.useradmin.ui.editor.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ace.useradmin.ui.editor.GroupNotFoundException;
+import org.apache.ace.useradmin.ui.editor.UserAlreadyExistsException;
+import org.apache.ace.useradmin.ui.editor.UserDTO;
+import org.apache.ace.useradmin.ui.editor.UserNotFoundException;
+import org.apache.ace.useradmin.ui.editor.UserEditor;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+/**
+ * An implementation of UserEditor. Can be used to execute operations on users in the useradminService;
+ */
+public class UserEditorImpl implements UserEditor {
+
+    private volatile UserAdmin m_useradmin;
+
+    @Override
+    public void addUser(UserDTO userDTO) throws GroupNotFoundException, UserAlreadyExistsException {
+        String username = userDTO.getUsername();
+        String password = userDTO.getPassword();
+        String groupname = userDTO.getGroupname();
+        if (username == null || "".equals(username) || password == null || "".equals(password) || groupname == null || "".equals(groupname)) {
+            throw new IllegalArgumentException("Username, password and groupname cannot be null or \"\"");
+        }
+        Group group = (Group) m_useradmin.getRole(groupname);
+        if (group == null) {
+            throw new GroupNotFoundException(groupname);
+        }
+        Role newRole = m_useradmin.createRole(username, Role.USER);
+        if (newRole == null) {
+            throw new UserAlreadyExistsException(username);
+        }
+        User newUser = (User) newRole;
+        newUser.getProperties().put("username", username);
+        newUser.getCredentials().put("password", password);
+        group.addMember(newUser);
+    }
+
+    public void storeUserDTO(UserDTO userDTO) throws UserNotFoundException, GroupNotFoundException, UserAlreadyExistsException {
+        if (userDTO.isUsernameChanged()) {
+            editUsername(userDTO);
+            return;
+        }
+        if (userDTO.isPasswordChanged()) {
+            editPassword(userDTO);
+        }
+        if (userDTO.isGroupChanged()) {
+            editGroup(userDTO);
+        }
+    }
+
+    @Override
+    public void editUsername(UserDTO userDTO) throws UserNotFoundException, GroupNotFoundException, UserAlreadyExistsException {
+        String oldUsername = userDTO.getPreviousUsername();
+        String newUsername = userDTO.getUsername();
+        if (oldUsername == null || newUsername == null || "".equals(newUsername)) {
+            throw new IllegalArgumentException("oldUsername and newUsername cannot be null or \"\" ");
+        }
+        if (newUsername.equals(oldUsername)) {
+            throw new UserAlreadyExistsException(newUsername);
+        }
+        if (getUser(newUsername) != null) {
+            throw new UserAlreadyExistsException(newUsername);
+        }
+        User user = getUser(oldUsername);
+        if (user == null) {
+            throw new UserNotFoundException(oldUsername);
+        }
+        String group = getGroup(user).getName();
+        if (group == null) {
+            throw new GroupNotFoundException(null);
+        }
+        addUser(userDTO);
+        removeUser(userDTO);
+    }
+
+    @Override
+    public void editPassword(UserDTO userDTO) throws UserNotFoundException {
+        String username = userDTO.getUsername();
+        String password = userDTO.getPassword();
+        if (username == null || password == null || "".equals(password)) {
+            throw new IllegalArgumentException("Username or Password cannot be null or \"\" ");
+        }
+        User user = getUser(username);
+        if (user == null) {
+            throw new UserNotFoundException(username);
+
+        }
+        user.getCredentials().put("password", password);
+    }
+
+    @Override
+    public void editGroup(UserDTO userDTO) throws UserNotFoundException, GroupNotFoundException {
+        String username = userDTO.getUsername();
+        String group = userDTO.getGroupname();
+        if (username == null || group == null) {
+            throw new IllegalArgumentException("Username and group cannot be null or \"\" ");
+        }
+        User user = getUser(username);
+        Group newGroup = (Group) m_useradmin.getRole(group);
+        if (newGroup == null) {
+            throw new GroupNotFoundException(group);
+        }
+        if (user == null) {
+            throw new UserNotFoundException(username);
+        }
+        getGroup(user).removeMember(user);
+        newGroup.addMember(user);
+    }
+
+    @Override
+    public void removeUser(UserDTO userDTO) throws UserNotFoundException {
+        String username = userDTO.getPreviousUsername();
+        if (username == null) {
+            throw new IllegalArgumentException("Username cannot be null or \"\" ");
+        }
+        User user = getUser(username);
+        if (user == null) {
+            throw new UserNotFoundException(username);
+        }
+        Group group = getGroup(user);
+        group.removeMember(user);
+        m_useradmin.removeRole(user.getName());
+    }
+
+    @Override
+    public List<UserDTO> getData() {
+        List<UserDTO> tempData = new ArrayList<UserDTO>();
+        try {
+            Role[] roles = m_useradmin.getRoles(null);
+            for (Role role : roles) {
+                if (role.getType() == Role.USER) {
+                    User user = (User) role;
+                    tempData.add(new UserDTO((User) role, getGroup(user)));
+                }
+            }
+        }
+        catch (InvalidSyntaxException e) {
+            throw new RuntimeException(e);
+        }
+        return tempData;
+    }
+
+    @Override
+    public List<Group> getGroups() {
+        List<Group> tempGroups = new ArrayList<Group>();
+        try {
+            Role[] roles = m_useradmin.getRoles("(type=userGroup)");
+            for (Role role : roles) {
+                if (role.getType() == Role.GROUP) {
+                    tempGroups.add((Group) role);
+                }
+            }
+        }
+        catch (InvalidSyntaxException e) {
+            throw new RuntimeException(e);
+        }
+        return tempGroups;
+    }
+
+    @Override
+    public List<User> getUsers() {
+        List<User> tempUsers = new ArrayList<User>();
+        try {
+            Role[] roles = m_useradmin.getRoles(null);
+            for (Role role : roles) {
+                if (role.getType() == Role.USER) {
+                    tempUsers.add((User) role);
+                }
+            }
+        }
+        catch (InvalidSyntaxException e) {
+            throw new RuntimeException(e);
+        }
+        return tempUsers;
+    }
+
+    @Override
+    public Group getGroup(User user) {
+        Authorization auth = m_useradmin.getAuthorization(user);
+        String[] roles = auth.getRoles();
+        if (roles != null) {
+            for (String role : roles) {
+                Role result = m_useradmin.getRole(role);
+                if (result.getType() == Role.GROUP) {
+                    Group group = (Group) result;
+                    for (Role r : group.getMembers()) {
+                        if (r.getType() == Role.USER && r.getName().equals(user.getName())) {
+                            return group;
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public User getUser(String username) {
+        return m_useradmin.getUser("username", username);
+    }
+
+    @Override
+    public boolean hasRole(User user, String role) {
+        Authorization authorization = m_useradmin.getAuthorization(user);
+        return authorization.hasRole(role);
+    }
+}

Added: ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/osgi/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/osgi/Activator.java?rev=1412355&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/osgi/Activator.java (added)
+++ ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/osgi/Activator.java Wed Nov 21 23:11:26 2012
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ace.useradmin.ui.osgi;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.ace.useradmin.ui.editor.UserEditor;
+import org.apache.ace.useradmin.ui.editor.impl.UserEditorImpl;
+import org.apache.ace.useradmin.ui.vaadin.UserAdminButton;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+
+public class Activator extends DependencyActivatorBase {
+    @Override
+    public void init(BundleContext context, final DependencyManager manager) throws Exception {
+        manager.add(createComponent()
+            .setInterface(UserEditor.class.getName(), null)
+            .setImplementation(UserEditorImpl.class)
+            .add(createServiceDependency()
+                .setService(UserAdmin.class)
+                .setRequired(true)
+            )
+        );
+        Properties properties = new Properties();
+        properties.put(UIExtensionFactory.EXTENSION_POINT_KEY, UIExtensionFactory.EXTENSION_POINT_VALUE_MENU);
+        manager.add(createComponent()
+            .setInterface(UIExtensionFactory.class.getName(), properties)
+            .setImplementation(new UIExtensionFactory() {
+                    @Override
+                    public Component create(Map<String, Object> context) {
+                        Button b = new UserAdminButton((User) context.get("user"));
+                        manager.add(createComponent()
+                            .setImplementation(b)
+                            .add(createServiceDependency()
+                                .setService(UserEditor.class)
+                                .setRequired(true)
+                            )
+                        );
+                        b.setDescription("This button opens a window to manage users");
+                        return b;
+                    }
+                }
+            )
+        );
+    }
+
+    @Override
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+    }
+}

Added: ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminButton.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminButton.java?rev=1412355&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminButton.java (added)
+++ ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminButton.java Wed Nov 21 23:11:26 2012
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ace.useradmin.ui.vaadin;
+
+import org.apache.ace.useradmin.ui.editor.UserEditor;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.useradmin.User;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Window;
+
+public class UserAdminButton extends Button {
+
+    private final User m_currentUser;
+    private volatile UserEditor m_userUtil;
+    private volatile Component m_window;
+    private volatile ClickListener m_click;
+
+    public UserAdminButton(User currentUser) {
+        m_currentUser = currentUser;
+        setEnabled(false);
+    }
+
+    public void init(Component component) {
+        final DependencyManager dm = component.getDependencyManager();
+        setEnabled(true);
+        if (m_userUtil.hasRole(m_currentUser, "editUsers")) {
+            setCaption("Manage Users");
+        }
+        else {
+            setCaption("My Info");
+        }
+        final Window window = new UserAdminWindow(m_currentUser);
+        window.setModal(true);
+        // create a new dependency for the window
+        m_window = dm.createComponent()
+            .setImplementation(window)
+            .add(dm.createServiceDependency()
+                .setService(UserEditor.class)
+                .setRequired(true)
+            );
+        dm.add(m_window);
+        m_click = new ClickListener() {
+            @Override
+            public void buttonClick(ClickEvent event) {
+                getWindow().addWindow(window);
+            }
+        };
+        addListener(m_click);
+    }
+
+    public void destroy(Component component) {
+        setEnabled(false);
+        component.getDependencyManager().remove(m_window);
+        removeListener(m_click);
+        setDescription("This service seems to be unavailable at this moment...");
+    }
+}

Added: ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminWindow.java?rev=1412355&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminWindow.java (added)
+++ ace/trunk/org.apache.ace.useradmin.ui/src/org/apache/ace/useradmin/ui/vaadin/UserAdminWindow.java Wed Nov 21 23:11:26 2012
@@ -0,0 +1,635 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.ace.useradmin.ui.vaadin;
+
+import java.util.List;
+
+import org.apache.ace.useradmin.ui.editor.GroupNotFoundException;
+import org.apache.ace.useradmin.ui.editor.UserAlreadyExistsException;
+import org.apache.ace.useradmin.ui.editor.UserDTO;
+import org.apache.ace.useradmin.ui.editor.UserNotFoundException;
+import org.apache.ace.useradmin.ui.editor.UserEditor;
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.User;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.PasswordField;
+import com.vaadin.ui.Select;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+/**
+ * UserAdminWindow is the user management window which handles changes made to ACE users. It provides an option to
+ * perform CRUD operations on ACE users. The changes are made by calls to userUtilImpl which calls Felix's UserAdmin.
+ * 
+ */
+@SuppressWarnings("serial")
+public class UserAdminWindow extends Window {
+
+    private final Table m_userTable;
+    private final Select m_groupSelect;
+    private final TextField m_usernameTextField;
+    private final PasswordField m_passwordTextField;
+    private final Button m_addNewUserButton;
+    private final Button m_cancelNewUserButton;
+    private final Button m_applyButton;
+    private final Button m_removeUserButton;
+    private ItemClickListener m_itemClickListener;
+    private UserDTO m_userDTO;
+    private volatile UserEditor m_userUtil;
+    private final User m_currentUser;
+    private boolean adminMode;
+
+    public UserAdminWindow(User currentUser) {
+        m_userTable = new Table();
+        m_groupSelect = new Select();
+        m_usernameTextField = new TextField();
+        m_passwordTextField = new PasswordField();
+        m_addNewUserButton = new Button();
+        m_cancelNewUserButton = new Button();
+        m_applyButton = new Button();
+        m_removeUserButton = new Button();
+        m_currentUser = currentUser;
+    }
+
+    public void init() {
+        setCaption("Manage users");
+        if (m_userUtil.hasRole(m_currentUser, "editUsers")) {
+            adminMode = true;
+            getLayout().setSizeFull();
+            addComponent(createAdminWindowLayout());
+            populateUserTableAndSelect();
+        }
+        else {
+            setCaption("My info");
+            addComponent(createUserWindowLayout());
+            populateSelect();
+            showApplyButton();
+            initializeUserDTO();
+        }
+    }
+
+    /**
+     * Will be called when a dependency isn't available
+     */
+    public void destroy() {
+        if (adminMode) {
+            getApplication().getMainWindow().showNotification("Oops", "Manage Users function has been disabled", Notification.TYPE_ERROR_MESSAGE);
+        }
+        else {
+            getApplication().getMainWindow().showNotification("Oops", "My info function has been disabled", Notification.TYPE_ERROR_MESSAGE);
+        }
+        close();
+        getApplication().removeWindow(this);
+    }
+
+    private void initializeUserDTO() {
+        m_userDTO = new UserDTO((String) m_currentUser.getProperties().get("username"), (String) m_currentUser.getCredentials().get("password"), m_userUtil.getGroup(m_currentUser).getName());
+        m_usernameTextField.setValue(m_userDTO.getUsername());
+        m_passwordTextField.setValue(m_userDTO.getPassword());
+        m_groupSelect.setValue(m_userDTO.getGroupname());
+        disableUsernameAndGroup();
+    }
+
+    /**
+     * Creates a new Layout containing the user table and edit form
+     * 
+     * @returns the manage users window
+     */
+    private HorizontalLayout createAdminWindowLayout() {
+        getWindow().setWidth("40%");
+        HorizontalLayout horizontalLayout = new HorizontalLayout();
+        horizontalLayout.setSizeFull();
+        horizontalLayout.addComponent(createFirstColumn());
+        horizontalLayout.addComponent(createFormLayout());
+        return horizontalLayout;
+    }
+
+    /**
+     * Create a new Layout containing with only the information of the logged user
+     * 
+     * @return
+     */
+    private HorizontalLayout createUserWindowLayout() {
+        getWindow().setHeight("25%");
+        getWindow().setWidth("20%");
+        HorizontalLayout horizontalLayout = new HorizontalLayout();
+        horizontalLayout.addComponent(createFormLayout());
+        return horizontalLayout;
+    }
+
+    /**
+     * Creates the left column containing the user table
+     * 
+     * @returns the user table column
+     */
+    private VerticalLayout createFirstColumn() {
+        VerticalLayout verticalLayout = new VerticalLayout();
+        verticalLayout.setSizeFull();
+        verticalLayout.setMargin(false, true, false, false);
+        Table table = initTable();
+        verticalLayout.addComponent(table);
+        HorizontalLayout buttons = createHorizontalButtonLayout();
+        verticalLayout.addComponent(buttons);
+        verticalLayout.setExpandRatio(table, 1.0f);
+        verticalLayout.setExpandRatio(buttons, 0.0f);
+        return verticalLayout;
+    }
+
+    /**
+     * Creates the form containing fields to edit user data
+     * 
+     * @returns the user edit fields
+     */
+    private FormLayout createFormLayout() {
+        FormLayout formLayout = new FormLayout();
+        formLayout.setMargin(false, false, false, true);
+        formLayout.addComponent(initUsernameTextField());
+        formLayout.addComponent(initPasswordField());
+        formLayout.addComponent(initSelect());
+        HorizontalLayout addUserButtons = new HorizontalLayout();
+        addUserButtons.addComponent(initApplyButton());
+        Button initializeAddNewUserButton = initializeAddNewUserButton();
+        addUserButtons.addComponent(initializeAddNewUserButton);
+        // addUserButtons.setComponentAlignment(initializeAddNewUserButton, Alignment.MIDDLE_CENTER);
+        addUserButtons.setSpacing(true);
+        addUserButtons.addComponent(initCancelNewUserButton());
+
+        formLayout.addComponent(addUserButtons);
+        hideNewUserButtons();
+        disableTextFieldsAndSelect();
+        return formLayout;
+    }
+
+    /**
+     * Creates a Layout containing the + and - button for addition and removal of users
+     * 
+     * @returns the button layout containing + and - buttons
+     */
+    private HorizontalLayout createHorizontalButtonLayout() {
+        HorizontalLayout horizontalLayout = new HorizontalLayout();
+        horizontalLayout.setMargin(true, false, true, false);
+        horizontalLayout.setSpacing(true);
+        horizontalLayout.addComponent(createAddButton());
+        horizontalLayout.addComponent(createRemoveButton());
+        return horizontalLayout;
+    }
+
+    /**
+     * Initializes the user table
+     * 
+     * @returns the usertable
+     */
+    private Table initTable() {
+        m_userTable.setSizeFull();
+        m_userTable.setSelectable(true);
+        m_userTable.setPageLength(0);
+        m_userTable.addContainerProperty("User", UserDTO.class, null);
+        m_userTable.setSortDisabled(false);
+        m_userTable.addListener(createUserTableSelectListener());
+        return m_userTable;
+    }
+
+    /**
+     * Creates a ClickListener to update the table selection
+     * 
+     * @returns a user table selection listener
+     */
+    private ItemClickListener createUserTableSelectListener() {
+        m_itemClickListener = new ItemClickListener() {
+
+            @Override
+            public void itemClick(ItemClickEvent event) {
+                enableTextFieldsAndSelect();
+                hideNewUserButtons();
+                showApplyButton();
+                UserDTO user = (UserDTO) event.getItem().getItemProperty("User").getValue();
+                m_userTable.select(user);
+                m_userDTO = new UserDTO(user.getUsername(), user.getPassword(), user.getGroupname());
+                m_usernameTextField.setValue(user.getUsername());
+                m_passwordTextField.setValue(user.getPassword());
+                m_groupSelect.setValue(user.getGroupname());
+                checkSameUser(m_userDTO.getUsername());
+            }
+        };
+        return m_itemClickListener;
+    }
+
+    /**
+     * Inserts inital user data into the user table
+     */
+    private void populateUserTableAndSelect() {
+        m_userTable.removeAllItems();
+        List<UserDTO> data = m_userUtil.getData();
+        for (UserDTO userDTO : data) {
+            m_userTable.addItem(new Object[] { userDTO }, userDTO);
+        }
+        populateSelect();
+    }
+
+    private void populateSelect() {
+        List<Group> grouplist = m_userUtil.getGroups();
+        for (Group g : grouplist) {
+            m_groupSelect.addItem(g.getName());
+        }
+        m_userTable.sort(new Object[] { "User" }, new boolean[] { true });
+    }
+
+    /**
+     * Creates the + button for creation of new users
+     * 
+     * @returns the + button
+     */
+    private Button createAddButton() {
+        Button b = new Button("+");
+        b.setWidth("4em");
+        b.addListener(new ClickListener() {
+
+            @Override
+            public void buttonClick(final ClickEvent event) {
+                enableTextFieldsAndSelect();
+                m_usernameTextField.setValue("");
+                m_passwordTextField.setValue("");
+                m_groupSelect.setValue(null);
+                m_userTable.select(null);
+                m_usernameTextField.focus();
+                showNewUserButtons();
+            }
+        });
+        return b;
+    }
+
+    /**
+     * Initializes the - button for removal of existing users
+     * 
+     * @returns the - button
+     */
+    private Button createRemoveButton() {
+        m_removeUserButton.setCaption("-");
+        m_removeUserButton.setWidth("4em");
+        m_removeUserButton.addListener(new ClickListener() {
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                try {
+                    if (m_userTable.getValue() == null) {
+                        return;
+                    }
+                    m_userUtil.removeUser(m_userDTO);
+                    m_userTable.removeItem(m_userTable.getValue());
+                    m_usernameTextField.setValue("");
+                    m_passwordTextField.setValue("");
+                    m_groupSelect.select(null);
+                    disableTextFieldsAndSelect();
+                }
+                catch (UserNotFoundException e) {
+                    showUserNotFoundWarning();
+                }
+            }
+        });
+        return m_removeUserButton;
+    }
+
+    /**
+     * Initializes the apply button to save changes after editing
+     * 
+     * @returns the apply button
+     */
+    private Button initApplyButton() {
+        m_applyButton.setCaption("Apply");
+        m_applyButton.addListener(new ClickListener() {
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                String usernameTextFieldInput = (String) m_usernameTextField.getValue();
+                if (usernameTextFieldInput == null || "".equals(usernameTextFieldInput)) {
+                    getWindow().showNotification("Username cannot be empty", Window.Notification.TYPE_WARNING_MESSAGE);
+                    return;
+                }
+                String groupName = (String) m_groupSelect.getValue();
+                if (groupName == null || "".equals(groupName)) {
+
+                    getWindow().showNotification("Role cannot be empty", Window.Notification.TYPE_WARNING_MESSAGE);
+                    return;
+                }
+                String passwordTextFieldInput = (String) m_passwordTextField.getValue();
+                if (passwordTextFieldInput == null || "".equals(passwordTextFieldInput)) {
+                    getWindow().showNotification("Password cannot be empty", Window.Notification.TYPE_WARNING_MESSAGE);
+                    return;
+                }
+                try {
+
+                    if (m_userDTO.isUpdated()) {
+                        m_userUtil.storeUserDTO(m_userDTO);
+                        if (adminMode) {
+                            UserDTO userDTO = new UserDTO(m_userDTO.getUsername(), m_userDTO.getPassword(), m_userDTO.getGroupname());
+                            m_userTable.removeItem(m_userTable.getValue());
+                            m_userTable.addItem(new Object[] { userDTO }, userDTO);
+                            m_userTable.sort(new Object[] { "User" }, new boolean[] { true });
+                            m_itemClickListener.itemClick(new ItemClickEvent((Component) event.getSource(), m_userTable.getItem(userDTO), null, null, null));
+                        }
+                        getWindow().showNotification("User updated");
+
+                    }
+                }
+                catch (UserNotFoundException e) {
+                    showUserNotFoundWarning();
+                }
+                catch (GroupNotFoundException e) {
+                    showGroupNotFoundWarning();
+                }
+                catch (UserAlreadyExistsException e) {
+                    showUserAlreadyExistsWarning();
+                }
+            }
+        });
+        return m_applyButton;
+    }
+
+    /**
+     * Initializes the cancel button which cancels the addition of a new user
+     * 
+     * @returns the cancel button
+     */
+    private Button initCancelNewUserButton() {
+        m_cancelNewUserButton.setCaption("Cancel");
+        m_cancelNewUserButton.addListener(new ClickListener() {
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                hideNewUserButtons();
+                m_userTable.select(null);
+                disableTextFieldsAndSelect();
+            }
+        });
+        return m_cancelNewUserButton;
+    }
+
+    /**
+     * Initializes the add button which checks if the input is valid, and then saves a new user to UserAdmin
+     * 
+     * @returns the add button
+     */
+    private Button initializeAddNewUserButton() {
+        m_addNewUserButton.setCaption("Add");
+        m_addNewUserButton.setWidth("5em");
+        m_addNewUserButton.addListener(new ClickListener() {
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                String username = (String) m_usernameTextField.getValue();
+                String password = (String) m_passwordTextField.getValue();
+                String group = (String) m_groupSelect.getValue();
+                if (username == null || "".equals(username) || password == null || "".equals(password) || group == null || "".equals(group)) {
+                    showEmptyInputWarning();
+                }
+                else {
+                    try {
+                        UserDTO userDTO = new UserDTO(username, password, group);
+                        m_userUtil.addUser(userDTO);
+                        m_userTable.addItem(new Object[] { userDTO }, userDTO);
+                        m_userTable.sort(new Object[] { "User" }, new boolean[] { true });
+                        m_userTable.select(username);
+                        m_itemClickListener.itemClick(new ItemClickEvent((Component) event.getSource(), m_userTable.getItem(userDTO), null, null, null));
+                    }
+                    catch (GroupNotFoundException e) {
+                        showGroupNotFoundWarning();
+                    }
+                    catch (UserAlreadyExistsException e) {
+                        showUserAlreadyExistsWarning();
+                    }
+                }
+            }
+        });
+        return m_addNewUserButton;
+    }
+
+    /**
+     * Initializes the username text field
+     * 
+     * @returns the username text field
+     */
+    private TextField initUsernameTextField() {
+        m_usernameTextField.setCaption("Username: ");
+        m_usernameTextField.setImmediate(true);
+        m_usernameTextField.addListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+                UserDTO user = (UserDTO) m_userTable.getValue();
+                if (user == null) {
+                    return;
+                }
+                if (m_userUtil.getUser(user.getUsername()) == null) {
+                    return;
+                }
+                String usernameTextFieldInput = (String) m_usernameTextField.getValue();
+                if (user.getUsername().equals(usernameTextFieldInput)) {
+                    if (!m_userDTO.getUsername().equals(usernameTextFieldInput)) {
+                        m_userDTO.setUsername(usernameTextFieldInput);
+                        m_userDTO.setUsernameChanged(false);
+                    }
+                    return;
+                }
+                m_userDTO.setUsername(usernameTextFieldInput);
+            }
+        });
+        return m_usernameTextField;
+    }
+
+    /**
+     * Initializes the password field
+     * 
+     * @returns the password field
+     */
+    private PasswordField initPasswordField() {
+        m_passwordTextField.setCaption("Password: ");
+        m_passwordTextField.setImmediate(true);
+        m_passwordTextField.addListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+                UserDTO user = m_userDTO;
+                if (user == null) {
+                    return;
+                }
+                User result = m_userUtil.getUser(user.getPreviousUsername());
+                if (result == null) {
+                    return;
+                }
+                String password = (String) result.getCredentials().get("password");
+                String passwordTextFieldInput = (String) m_passwordTextField.getValue();
+                if (password.equals(passwordTextFieldInput)) {
+                    if (!m_userDTO.getPassword().equals(passwordTextFieldInput)) {
+                        m_userDTO.setPassword(passwordTextFieldInput);
+                        m_userDTO.setPasswordChanged(false);
+                    }
+                    return;
+                }
+                m_userDTO.setPassword(passwordTextFieldInput);
+            }
+        });
+        return m_passwordTextField;
+    }
+
+    /**
+     * Initializes the group select box
+     * 
+     * @returns the group select
+     */
+    private Select initSelect() {
+        m_groupSelect.setCaption("Role: ");
+        m_groupSelect.setImmediate(true);
+        m_groupSelect.setSizeFull();
+        m_groupSelect.setNullSelectionAllowed(false);
+        m_groupSelect.addListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+                UserDTO user = (UserDTO) m_userTable.getValue();
+                if (user == null) {
+                    return;
+                }
+                User result = m_userUtil.getUser(user.getUsername());
+                if (result == null) {
+                    return;
+                }
+                Group group = m_userUtil.getGroup(result);
+                String groupName = (String) m_groupSelect.getValue();
+                if (group.getName().equals(groupName)) {
+                    if (!m_userDTO.getGroupname().equals(groupName)) {
+                        m_userDTO.setGroupname(groupName);
+                        m_userDTO.setGroupChanged(false);
+                    }
+                    return;
+                }
+                m_userDTO.setGroupname(groupName);
+            }
+        });
+        return m_groupSelect;
+    }
+
+    /**
+     * Enables the username, password and group select form
+     */
+    private void enableTextFieldsAndSelect() {
+        m_usernameTextField.setEnabled(true);
+        m_passwordTextField.setEnabled(true);
+        m_groupSelect.setEnabled(true);
+        m_removeUserButton.setEnabled(true);
+    }
+
+    /**
+     * Disables the username, password and group select form
+     */
+    private void disableTextFieldsAndSelect() {
+        m_usernameTextField.setEnabled(false);
+        m_passwordTextField.setEnabled(false);
+        m_groupSelect.setEnabled(false);
+        m_removeUserButton.setEnabled(false);
+        hideApplyButton();
+    }
+
+    private void disableUsernameAndGroup() {
+        m_usernameTextField.setEnabled(false);
+        m_passwordTextField.setEnabled(true);
+        m_groupSelect.setEnabled(false);
+        m_removeUserButton.setEnabled(false);
+    }
+
+    private void checkSameUser(String currentUser) {
+        if (m_currentUser.getProperties().get("username").equals(m_userUtil.getUser(currentUser).getProperties().get("username"))) {
+            disableUsernameAndGroup();
+        }
+        else {
+            enableTextFieldsAndSelect();
+        }
+    }
+
+    /**
+     * Shows the add and cancel buttons when adding a new user
+     */
+    private void showNewUserButtons() {
+        m_addNewUserButton.setVisible(true);
+        m_cancelNewUserButton.setVisible(true);
+        m_usernameTextField.setValue("");
+        m_passwordTextField.setValue("");
+        m_groupSelect.setValue(null);
+        m_removeUserButton.setEnabled(false);
+        hideApplyButton();
+    }
+
+    /**
+     * Hides the add and cancel buttons when adding a new user
+     */
+    private void hideNewUserButtons() {
+        m_addNewUserButton.setVisible(false);
+        m_cancelNewUserButton.setVisible(false);
+        m_usernameTextField.setValue("");
+        m_passwordTextField.setValue("");
+        m_groupSelect.setValue(null);
+    }
+
+    private void showApplyButton() {
+        m_applyButton.setVisible(true);
+    }
+
+    private void hideApplyButton() {
+        m_applyButton.setVisible(false);
+    }
+
+    /**
+     * Displays an error when the requested user is not found
+     */
+    private void showUserNotFoundWarning() {
+        getWindow().showNotification("Oops:", "<br>User not found, please refresh</br>", Window.Notification.TYPE_WARNING_MESSAGE);
+    }
+
+    /**
+     * Displays an error that the given username is already in use
+     */
+    private void showUserAlreadyExistsWarning() {
+        getWindow().showNotification("Oops:", "<br>Username already in use</br>", Window.Notification.TYPE_WARNING_MESSAGE);
+    }
+
+    /**
+     * Displays an error that the selected group is not found
+     */
+    private void showGroupNotFoundWarning() {
+        getWindow().showNotification("Error:", "<br>Group not found, please refresh</br>", Window.Notification.TYPE_WARNING_MESSAGE);
+    }
+
+    /**
+     * Displays an error message regarding empty input
+     */
+    private void showEmptyInputWarning() {
+        getWindow().showNotification("Oops:", "<br>Username, password & group cannot be empty</br>", Window.Notification.TYPE_WARNING_MESSAGE);
+    }
+}

Modified: ace/trunk/run-server/conf/org.apache.ace.server.repository.factory/ace-user.cfg
URL: http://svn.apache.org/viewvc/ace/trunk/run-server/conf/org.apache.ace.server.repository.factory/ace-user.cfg?rev=1412355&r1=1412354&r2=1412355&view=diff
==============================================================================
--- ace/trunk/run-server/conf/org.apache.ace.server.repository.factory/ace-user.cfg (original)
+++ ace/trunk/run-server/conf/org.apache.ace.server.repository.factory/ace-user.cfg Wed Nov 21 23:11:26 2012
@@ -132,6 +132,11 @@ initial=<roles> \
                <type>permissionGroup</type> \
            </properties> \
        </group> \
+       <group name="editUsers"> \
+           <properties> \
+               <type>permissionGroup</type> \
+           </properties> \
+       </group> \
        <group name="TestGroup"> \
            <properties> \
                <type>userGroup</type> \
@@ -162,6 +167,7 @@ initial=<roles> \
            <memberof>registerTarget</memberof> \
            <memberof>removeDistributionToTargetAssociation</memberof> \
            <memberof>mock</memberof> \
+           <memberof>editUsers</memberof> \
        </group> \
        <group name="Target Operator"> \
            <properties> \

Modified: ace/trunk/run-server/server.bndrun
URL: http://svn.apache.org/viewvc/ace/trunk/run-server/server.bndrun?rev=1412355&r1=1412354&r2=1412355&view=diff
==============================================================================
--- ace/trunk/run-server/server.bndrun (original)
+++ ace/trunk/run-server/server.bndrun Wed Nov 21 23:11:26 2012
@@ -56,7 +56,8 @@
 	org.apache.ace.deployment.verifier;version=latest,\
 	org.apache.ace.client.repository.helper.base;version=latest,\
 	org.apache.ace.authenticationprocessor.basicauth;version=latest,\
-	org.apache.ace.nodelauncher.ui;version=latest
+	org.apache.ace.nodelauncher.ui;version=latest,\
+	org.apache.ace.useradmin.ui;version=latest
 -runrepos: Workspace,\
 	Local Repository,\
 	Release