summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAppaRao Puli <apparao.puli@linux.intel.com>2018-10-17 16:07:55 +0530
committerEd Tanous <ed.tanous@intel.com>2019-01-02 01:12:37 +0000
commit28711a6ad2cff8277bfa537c3b140caf690ab575 (patch)
treec14285dbdb00d511f4b10909955513b7925c2912
parent0f2f981e3218a57f89995aa6cb6b684b2ec0ba8f (diff)
downloadphosphor-webui-28711a6ad2cff8277bfa537c3b140caf690ab575.tar.gz
phosphor-webui-28711a6ad2cff8277bfa537c3b140caf690ab575.zip
WebUI: User management full implementation.
Added webui user accounts management. This support both redfish and rest based backend API calls depending on redfishSupportEnabled flag. It does following actions: - View all user list and there properties like name, privilege, enabled state, Locked etc.. - Create new user account. - Delete existing user account. - Update the existing user properties like password, privilege, enabled state. Unit Test: - Viewed all user information is proper or not. - Created new user and validated. - Deleted specific user and checked. - Modified user info and validated the change. All tests are done by enabling and disabling redfishSupportEnabled flag using conifg.json. Change-Id: Ifecf63844dc42c44771509958bf75947a92997ac Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
-rw-r--r--app/common/directives/app-navigation.html2
-rw-r--r--app/common/services/api-utils.js284
-rw-r--r--app/users/controllers/user-accounts-controller.html103
-rw-r--r--app/users/controllers/user-accounts-controller.js180
-rw-r--r--app/users/styles/index.scss2
-rw-r--r--app/users/styles/user-accounts.scss26
6 files changed, 511 insertions, 86 deletions
diff --git a/app/common/directives/app-navigation.html b/app/common/directives/app-navigation.html
index 877f030..2f3ded7 100644
--- a/app/common/directives/app-navigation.html
+++ b/app/common/directives/app-navigation.html
@@ -98,6 +98,6 @@
</ul>
<ul class="nav__second-level btn-users" ng-style="navStyle" ng-class="{opened: (showSubMenu && firstLevel == 'users')}">
<li ng-class="{'active': (path == '/users' || path == '/users/manage-accounts')}">
- <a href="#/users/manage-accounts" tabindex="18" ng-click="closeSubnav()">Manage user account</a></li>
+ <a href="#/users/manage-accounts" tabindex="18" ng-click="closeSubnav()">Manage user accounts</a></li>
</ul>
</nav>
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index 31a2958..beb63ba 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -475,19 +475,6 @@ window.angular && (function(angular) {
console.log(error);
});
},
- testPassword: function(username, password) {
- // Calls /login without the current session to verify the given
- // password is correct ignore the interceptor logout on a bad password
- return $http({
- method: 'POST',
- url: DataService.getHost() + '/login',
- withCredentials: false,
- data: JSON.stringify({'data': [username, password]})
- })
- .then(function(response) {
- return response.data;
- });
- },
logout: function(callback) {
$http({
method: 'POST',
@@ -509,7 +496,7 @@ window.angular && (function(angular) {
});
},
changePassword: function(user, newPassword) {
- if (DataService.configJson.redfishSupportEnabled) {
+ if (DataService.configJson.redfishSupportEnabled == true) {
return $http({
method: 'PATCH',
url: DataService.getHost() +
@@ -539,6 +526,272 @@ window.angular && (function(angular) {
return deferred.promise;
}
},
+ getAllUserAccounts: function(members) {
+ var deferred = $q.defer();
+ var promises = [];
+ var users = [];
+
+ if (DataService.configJson.redfishSupportEnabled == true) {
+ $http({
+ method: 'GET',
+ url:
+ DataService.getHost() + '/redfish/v1/AccountService/Accounts',
+ withCredentials: true
+ })
+ .then(
+ function(response) {
+ var members = response.data['Members'];
+ angular.forEach(members, function(member) {
+ promises.push(
+ $http({
+ method: 'GET',
+ url: DataService.getHost() + member['@odata.id'],
+ withCredentials: true
+ }).then(function(res) {
+ return res.data;
+ }));
+ });
+
+ $q.all(promises).then(
+ function(results) {
+ deferred.resolve(results);
+ },
+ function(errors) {
+ deferred.reject(errors);
+ });
+ },
+ function(error) {
+ console.log(error);
+ deferred.reject(error);
+ });
+ } else {
+ $http({
+ method: 'GET',
+ url:
+ DataService.getHost() + '/xyz/openbmc_project/user/enumerate',
+ withCredentials: true
+ })
+ .then(
+ function(response) {
+ var json = JSON.stringify(response.data);
+ var content = JSON.parse(json);
+
+ function convertPrivToRoleId(priv) {
+ if (priv == 'priv-admin') {
+ return 'Administrator';
+ } else if (priv == 'priv-user') {
+ return 'User';
+ } else if (priv == 'priv-operator') {
+ return 'Operator';
+ } else if (priv == 'priv-callback') {
+ return 'Callback';
+ }
+ return '';
+ }
+
+ for (var key in content.data) {
+ var username = key.split('/').pop();
+ if (content.data.hasOwnProperty(key) &&
+ content.data[key].hasOwnProperty('UserPrivilege')) {
+ var val = content.data[key];
+ users.push(Object.assign({
+ Id: username,
+ UserName: username,
+ Locked: val['UserLockedForFailedAttempt'],
+ RoleId: convertPrivToRoleId(val['UserPrivilege']),
+ Enabled: val['UserEnabled'],
+ Password: null
+ }));
+ }
+ }
+ deferred.resolve(users);
+ },
+ function(error) {
+ console.log(error);
+ deferred.reject(error);
+ });
+ }
+ return deferred.promise;
+ },
+ createUser: function(user, passwd, role, enabled) {
+ if (DataService.configJson.redfishSupportEnabled == true) {
+ var data = {};
+ data['UserName'] = user;
+ data['Password'] = passwd;
+ data['RoleId'] = role;
+ data['Enabled'] = enabled;
+
+ return $http({
+ method: 'POST',
+ url:
+ DataService.getHost() + '/redfish/v1/AccountService/Accounts',
+ withCredentials: true,
+ data: data
+ });
+ } else {
+ function convertRoleIdToPriv(roleId) {
+ if (roleId == 'Administrator') {
+ return 'priv-admin';
+ } else if (roleId == 'User') {
+ return 'priv-user';
+ } else if (roleId == 'Operator') {
+ return 'priv-operator';
+ } else if (roleId == 'Callback') {
+ return 'priv-callback';
+ }
+ return '';
+ }
+ function setUserPassword(user, passwd) {
+ return $http({
+ method: 'POST',
+ url: DataService.getHost() +
+ '/xyz/openbmc_project/user/' + user +
+ '/action/SetPassword',
+ withCredentials: true,
+ data: JSON.stringify({'data': [passwd]}),
+ responseType: 'arraybuffer'
+ })
+ .then(function(response) {
+ return response.data;
+ });
+ }
+ var priv = convertRoleIdToPriv(role);
+ return $http({
+ method: 'POST',
+ url: DataService.getHost() +
+ '/xyz/openbmc_project/user/action/CreateUser',
+ withCredentials: true,
+ data: JSON.stringify({
+ 'data':
+ [user, ['web', 'redfish', 'ssh'], priv, enabled]
+ }),
+ responseType: 'arraybuffer'
+ })
+ .then(function(response) {
+ return setUserPassword(user, passwd);
+ });
+ }
+ },
+ updateUser: function(user, newUser, passwd, role, enabled) {
+ if (DataService.configJson.redfishSupportEnabled == true) {
+ var data = {};
+ if ((newUser !== undefined) && (newUser != null)) {
+ data['UserName'] = newUser;
+ }
+ if ((role !== undefined) && (role != null)) {
+ data['RoleId'] = role;
+ }
+ if ((enabled !== undefined) && (enabled != null)) {
+ data['Enabled'] = enabled;
+ }
+ if ((passwd !== undefined) && (passwd != null)) {
+ data['Password'] = passwd;
+ }
+ return $http({
+ method: 'PATCH',
+ url: DataService.getHost() +
+ '/redfish/v1/AccountService/Accounts/' + user,
+ withCredentials: true,
+ data: data
+ });
+ } else {
+ var deferred = $q.defer();
+ var promises = [];
+ function convertRoleIdToPriv(roleId) {
+ if (roleId == 'Administrator') {
+ return 'priv-admin';
+ } else if (roleId == 'User') {
+ return 'priv-user';
+ } else if (roleId == 'Operator') {
+ return 'priv-operator';
+ } else if (roleId == 'Callback') {
+ return 'priv-callback';
+ }
+ return '';
+ }
+ function setUserProperty(user, propKey, propVal) {
+ return $http({
+ method: 'PUT',
+ url: DataService.getHost() +
+ '/xyz/openbmc_project/user/' + user + '/attr/' +
+ propKey,
+ withCredentials: true,
+ data: JSON.stringify({'data': propVal})
+ })
+ .then(function(response) {
+ return response.data;
+ });
+ }
+ function setUserPassword(user, passwd) {
+ return $http({
+ method: 'POST',
+ url: DataService.getHost() +
+ '/xyz/openbmc_project/user/' + user +
+ '/action/SetPassword',
+ withCredentials: true,
+ data: JSON.stringify({'data': [passwd]}),
+ responseType: 'arraybuffer'
+ })
+ .then(function(response) {
+ return response.data;
+ });
+ }
+ function renameUser(user, newUser) {
+ return $http({
+ method: 'POST',
+ url: DataService.getHost() +
+ '/xyz/openbmc_project/user/action/RenameUser',
+ withCredentials: true,
+ data: JSON.stringify({'data': [user, newUser]})
+ })
+ .then(function(response) {
+ return response.data;
+ });
+ }
+ if ((role !== undefined) && (role != null)) {
+ var priv = convertRoleIdToPriv(role);
+ promises.push(setUserProperty(user, 'UserPrivilege', priv));
+ }
+ if ((enabled !== undefined) && (enabled != null)) {
+ promises.push(setUserProperty(user, 'UserEnabled', enabled));
+ }
+ if ((passwd !== undefined) && (passwd != null)) {
+ promises.push(setUserPassword(user, passwd));
+ }
+ if ((newUser !== undefined) && (newUser != null)) {
+ promises.push(renameUser(user, newUser));
+ }
+ $q.all(promises).then(
+ function(results) {
+ deferred.resolve(results);
+ },
+ function(errors) {
+ deferred.reject(errors);
+ });
+ return deferred.promise;
+ }
+ },
+ deleteUser: function(user) {
+ if (DataService.configJson.redfishSupportEnabled == true) {
+ return $http({
+ method: 'DELETE',
+ url: DataService.getHost() +
+ '/redfish/v1/AccountService/Accounts/' + user,
+ withCredentials: true,
+ });
+ } else {
+ return $http({
+ method: 'POST',
+ url: DataService.getHost() + '/xyz/openbmc_project/user/' +
+ user + '/action/Delete',
+ withCredentials: true,
+ data: JSON.stringify({'data': []})
+ })
+ .then(function(response) {
+ return response.data;
+ });
+ }
+ },
chassisPowerOff: function() {
var deferred = $q.defer();
$http({
@@ -1028,7 +1281,8 @@ window.angular && (function(angular) {
var activationStatus = '';
// If the image is "Functional" use that for the
- // activation status, else use the value of "Activation"
+ // activation status, else use the value of
+ // "Activation"
// github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml
if (content.data[key].Activation) {
activationStatus =
diff --git a/app/users/controllers/user-accounts-controller.html b/app/users/controllers/user-accounts-controller.html
index 9d388bc..d37c5e1 100644
--- a/app/users/controllers/user-accounts-controller.html
+++ b/app/users/controllers/user-accounts-controller.html
@@ -1,46 +1,95 @@
+<loader loading="loading"></loader>
<div id="user-accounts">
<div class="row column">
- <h1>Manage user account</h1>
- <div class="column small-12 page-header">
- <h2 class="h4">Change password</h2>
+ <h1>User account information</h1>
+ </div>
+ <div class="table row column" ng-show="users.length != 0">
+ <div class="table__head">
+ <div class="table__row">
+ <div class="table__cell"> Username </div>
+ <div class="table__cell"> Enabled </div>
+ <div class="table__cell"> Role </div>
+ <div class="table__cell"> Locked </div>
+ <div class="table__cell"> Action </div>
+ </div>
+ </div>
+ <div class="table__body">
+ <div class="table__row" ng-repeat="user in users">
+ <div class="table__cell"> {{user.UserName}} </div>
+ <div class="table__cell"> {{user.Enabled}} </div>
+ <div class="table__cell"> {{user.RoleId}} </div>
+ <div class="table__cell"> {{user.Locked}} </div>
+ <div class="table__cell">
+ <button type="button" class="btn-primary inline" ng-disabled="isUserSelected" ng-click="setSelectedUser(user)">Edit</button>
+ <button type="button" class="btn-primary inline" ng-disabled="isUserSelected" ng-click="deleteUser(user.UserName)">Delete</button>
+ </div>
+ </div>
</div>
</div>
- <section class="row column" aria-label="change password form">
- <form class="user-manage__form" role="form">
- <fieldset>
- <legend aria-label="user manager" class="accessible-text">Change password form</legend>
- <div class="row column">
- <label for="user-manage__current-password">Current password</label>
- <input id="user-manage__current-password" type="password" ng-model="oldPassword" class="user-manage__current-password inline" autocomplete="off"/>
+ <div class="table row column" ng-show="users.length == 0">
+ <span>No users exist in system</span>
+ </div>
+
+ <form role="form" class="user-manage__form">
+ <section class="row column" aria-label="user manage form">
+ <div class="column small-12 page-header">
+ <h2 class="inline h4">User account settings</h2>
+ </div>
+ <div class='col-sm-12'>
+ <label class="col-md-1 control-label">UserName</label>
+ <div class="col-md-3">
+ <input type="text" class="form-control" name="UserName" ng-model="selectedUser.UserName" />
+ </div>
</div>
- <div class="inline">
- <label for="user-manage__new-password">New password</label>
- <div class="user-manage__input-wrapper inline">
- <input id="user-manage__new-password" type="{{showpassword ? 'text' : 'password'}}" ng-model="password" class="user-manage__new-password inline" autocomplete="off"/>
+ <div class='col-sm-12 inline'>
+ <label class="col-md-1 control-label">Password</label>
+ <div class="col-md-3 user-manage__input-wrapper inline">
+ <input type="{{showpassword ? 'text' : 'password'}}" class="form-control user-manage__new-password inline" name="Password" ng-model="selectedUser.Password" autocomplete="off"/>
<button ng-model="showpassword" ng-click="togglePassword = !togglePassword; showpassword = !showpassword;" class="password-toggle">
<span ng-hide="togglePassword">Show</span>
<span ng-show="togglePassword">Hide</span>
</button>
</div>
</div>
- <div class="inline">
- <label for="user-manage__verify-password">Retype new password</label>
- <div class="user-manage__input-wrapper inline">
- <input id="user-manage__verify-password" type="{{showpasswordVerify ? 'text' : 'password'}}" ng-model="passwordVerify" class="user-manage__verify-password inline" autocomplete="off"/>
+ <div class='col-sm-12'>
+ <label class="col-md-1 control-label">Retype Password</label>
+ <div class="col-md-3 user-manage__input-wrapper inline">
+ <input type="{{showpasswordVerify ? 'text' : 'password'}}" class="form-control user-manage__verify-password inline" name="VerifyPassword" ng-model="selectedUser.VerifyPassword" autocomplete="off">
<button ng-model="showpasswordVerify" ng-click="toggleVerify = !toggleVerify; showpasswordVerify = !showpasswordVerify;" class="password-toggle">
<span ng-hide="toggleVerify">Show</span>
<span ng-show="toggleVerify">Hide</span>
</button>
</div>
</div>
- </fieldset>
- <div class="user-manage__submit-wrapper">
- <button class="btn-primary inline" ng-click="changePassword(oldPassword, password, passwordVerify)">Save change</button>
+ <div class='col-sm-12'>
+ <label class="col-md-1 control-label">Role</label>
+ <div class="col-md-3 user-manage__input-wrapper inline">
+ <select ng-model="selectedUser.RoleId" class="form-control inline">
+ <option ng-repeat="role in roles" class="inline">{{role}}</option>
+ </select>
+ </div>
+ </div>
+ <div class='col-sm-12'>
+ <label class="col-md-1 control-label">Enabled</label>
+ <div class="col-md-3 user-manage__input-wrapper inline">
+ <label class="control-check">
+ <input type="checkbox" name="Enabled" ng-model="selectedUser.Enabled"/>
+ <span class="control__indicator"></span>
+ </label>
+ </div>
+ </div>
+ <div class="user-manage__submit-wrapper">
+ <button type="button" class="btn-primary inline" ng-if="!isUserSelected" ng-click="createNewUser()">Create User</button>
+ <button type="button" class="btn-primary inline" ng-if="isUserSelected" ng-click="updateUserInfo()">Save</button>
+ <button type="button" class="btn-primary inline" ng-if="isUserSelected" ng-click="cancel()">Cancel</button>
+ </div>
+ </section>
+ <section class="row column">
+ <div class='col-sm-12'>
+ <p ng-class="'user-manage__' + state" role="alert">
+ {{outMsg}}
+ </p>
</div>
- <p ng-class="'change-password__' + state" role="alert">
- {{state === 'error' ? errorMsg : ''}}
- {{state === 'success' ? 'Success! User Password has been changed!' : ''}}
- </p>
- </form>
- </section>
+ </section>
+ </form>
</div>
diff --git a/app/users/controllers/user-accounts-controller.js b/app/users/controllers/user-accounts-controller.js
index 24a93cb..5f90844 100644
--- a/app/users/controllers/user-accounts-controller.js
+++ b/app/users/controllers/user-accounts-controller.js
@@ -10,58 +10,168 @@ window.angular && (function(angular) {
'use strict';
angular.module('app.users').controller('userAccountsController', [
- '$scope', '$window', 'APIUtils', 'dataService',
- function($scope, $window, APIUtils, dataService) {
- $scope.dataService = dataService;
+ '$scope', 'APIUtils',
+ function($scope, APIUtils) {
+ // TODO: Get the roles using Roles redfish URI.
+ $scope.roles = ['Administrator', 'Operator', 'User', 'Callback'];
$scope.state = 'none';
- $scope.errorMsg = '';
+ $scope.outMsg = '';
+ $scope.loading = true;
- $scope.changePassword = function(
- oldPassword, newPassword, confirmNewPassword) {
- var user = $scope.dataService.getUser();
- if (!oldPassword || !newPassword || !confirmNewPassword) {
+ function loadUserInfo() {
+ $scope.users = [];
+ $scope.loading = true;
+ $scope.isUserSelected = false;
+ $scope.selectedUser = null;
+
+ APIUtils.getAllUserAccounts()
+ .then(
+ function(res) {
+ $scope.users = res;
+ },
+ function(error) {
+ console.log(JSON.stringify(error));
+ })
+ .finally(function() {
+ $scope.loading = false;
+ });
+ };
+ $scope.cancel = function() {
+ $scope.state = 'none';
+ $scope.outMsg = '';
+ loadUserInfo();
+ };
+ $scope.setSelectedUser = function(user) {
+ $scope.state = 'none';
+ $scope.outMsg = '';
+
+ $scope.isUserSelected = true;
+ $scope.selectedUser = angular.copy(user);
+ $scope.selectedUser.VerifyPassword = null;
+ // Used while renaming the user.
+ $scope.selectedUser.CurrentUserName = $scope.selectedUser.UserName;
+ };
+ $scope.createNewUser = function() {
+ $scope.state = 'none';
+ $scope.outMsg = '';
+
+ if (!$scope.selectedUser.UserName || !$scope.selectedUser.Password) {
$scope.state = 'error';
- $scope.errorMsg = 'Field is required!';
- return false;
+ $scope.outMsg = 'Username or Password can\'t be empty';
+ return;
}
- if (newPassword !== confirmNewPassword) {
+ if ($scope.selectedUser.Password !==
+ $scope.selectedUser.VerifyPassword) {
$scope.state = 'error';
- $scope.errorMsg = 'New passwords do not match!';
- return false;
+ $scope.outMsg = 'Passwords do not match';
+ return;
+ }
+ var user = $scope.selectedUser.UserName;
+ var passwd = $scope.selectedUser.Password;
+ var role = $scope.selectedUser.RoleId;
+ var enabled = false;
+ if ($scope.selectedUser.Enabled != null) {
+ enabled = $scope.selectedUser.Enabled;
}
- if (newPassword === oldPassword) {
+
+ $scope.loading = true;
+ APIUtils.createUser(user, passwd, role, enabled)
+ .then(
+ function(response) {
+ $scope.state = 'success';
+ $scope.outMsg = 'User has been created successfully';
+ },
+ function(error) {
+ $scope.state = 'error';
+ if ((error.data.error['@Message.ExtendedInfo'] !=
+ undefined) &&
+ (error.data.error['@Message.ExtendedInfo'].length != 0)) {
+ $scope.outMsg =
+ error.data.error['@Message.ExtendedInfo'][0].Message;
+ } else {
+ $scope.outMsg = 'Failed to create new user.';
+ }
+ })
+ .finally(function() {
+ loadUserInfo();
+ $scope.loading = false;
+ });
+ };
+ $scope.updateUserInfo = function() {
+ $scope.state = 'none';
+ $scope.outMsg = '';
+ if ($scope.selectedUser.Password !==
+ $scope.selectedUser.VerifyPassword) {
$scope.state = 'error';
- $scope.errorMsg = 'New password and old password match!';
- return false;
+ $scope.outMsg = 'Passwords do not match';
+ return;
+ }
+ var data = {};
+ if ($scope.selectedUser.UserName !==
+ $scope.selectedUser.CurrentUserName) {
+ data['UserName'] = $scope.selectedUser.UserName;
}
+ $scope.selectedUser.VerifyPassword = null;
+ if ($scope.selectedUser.Password != null) {
+ data['Password'] = $scope.selectedUser.Password;
+ }
+ data['RoleId'] = $scope.selectedUser.RoleId;
+ data['Enabled'] = $scope.selectedUser.Enabled;
+
+ $scope.loading = true;
+ APIUtils
+ .updateUser(
+ $scope.selectedUser.CurrentUserName, data['UserName'],
+ data['Password'], data['RoleId'], data['Enabled'])
+ .then(
+ function(response) {
+ $scope.state = 'success';
+ $scope.outMsg = 'User has been updated successfully';
+ },
+ function(error) {
+ $scope.state = 'error';
+ if ((error.data.error['@Message.ExtendedInfo'] !=
+ undefined) &&
+ (error.data.error['@Message.ExtendedInfo'].length != 0)) {
+ $scope.outMsg =
+ error.data.error['@Message.ExtendedInfo'][0].Message;
+ } else {
+ $scope.outMsg = 'Updating user failed.';
+ }
+ })
+ .finally(function() {
+ loadUserInfo();
+ $scope.loading = false;
+ });
+ };
+ $scope.deleteUser = function(userName) {
+ $scope.state = 'none';
+ $scope.outMsg = '';
- // Verify the oldPassword is correct
- dataService.ignoreHttpError = true;
- APIUtils.testPassword(user, oldPassword)
+ $scope.loading = true;
+ APIUtils.deleteUser(userName)
.then(
- function(state) {
- APIUtils.changePassword(user, newPassword)
- .then(
- function(response) {
- // Clear the textboxes on a success
- $scope.passwordVerify = '';
- $scope.password = '';
- $scope.oldPassword = '';
- $scope.state = 'success';
- },
- function(error) {
- $scope.state = 'error';
- $scope.errorMsg = 'Error changing password!';
- });
+ function(response) {
+ $scope.state = 'success';
+ $scope.outMsg = 'User has been deleted successfully';
},
function(error) {
$scope.state = 'error';
- $scope.errorMsg = 'Old password is not correct!';
+ if ((error.data.error['@Message.ExtendedInfo'] !=
+ undefined) &&
+ (error.data.error['@Message.ExtendedInfo'].length != 0)) {
+ $scope.outMsg =
+ error.data.error['@Message.ExtendedInfo'][0].Message;
+ } else {
+ $scope.outMsg = 'Deleting user failed.';
+ }
})
.finally(function() {
- dataService.ignoreHttpError = false;
+ loadUserInfo();
+ $scope.loading = false;
});
};
+ loadUserInfo();
}
]);
})(angular);
diff --git a/app/users/styles/index.scss b/app/users/styles/index.scss
index 5162e09..da9c25e 100644
--- a/app/users/styles/index.scss
+++ b/app/users/styles/index.scss
@@ -1 +1 @@
-@import "./user-accounts.scss"; \ No newline at end of file
+@import "./user-accounts.scss";
diff --git a/app/users/styles/user-accounts.scss b/app/users/styles/user-accounts.scss
index 891b3a9..fb6d162 100644
--- a/app/users/styles/user-accounts.scss
+++ b/app/users/styles/user-accounts.scss
@@ -2,6 +2,9 @@ $userInputHeight: 40px;
.user-manage__form {
width: 100%;
+ .dropdown__button {
+ margin-bottom: 1.2em;
+ }
label {
width: 100%;
min-width: 210px;
@@ -12,13 +15,16 @@ $userInputHeight: 40px;
width: 225px;
height: $userInputHeight;
}
+ select {
+ width: 225px;
+ height: $userInputHeight;
+ }
fieldset {
display: block;
padding-left: 1.5em;
margin-bottom: 1em;
border-bottom: 1px solid $medgrey;
}
-
.user-manage__input-wrapper {
position: relative;
height: $userInputHeight;
@@ -31,15 +37,22 @@ $userInputHeight: 40px;
position: absolute;
right: 5px;
padding: 3px;
+ margin-right: 20px;
color: $primebtn__bg;
font-size: .8em;
@include vertCenter;
}
- .user-manage__submit-wrapper button {
- float: right;
- margin-left: .5em;
+ .user-manage__submit-wrapper {
+ width: 100%;
+ margin-top: 3em;
+ padding-top: 1em;
+ border-top: 1px solid $medgrey;
+ button {
+ float: right;
+ margin: .5em;
+ }
}
- .change-password__error
+ .user-manage__error
{
background: lighten($error-color, 20%);
padding: 1em;
@@ -49,9 +62,8 @@ $userInputHeight: 40px;
color: $black;
font-family: "Courier New", Helvetica, Arial, sans-serif;
font-weight: 700;
- width: 325px;
}
- .change-password__success
+ .user-manage__success
{
color: $primebtn__bg;
padding: 1em;
OpenPOWER on IntegriCloud