Browse Source

permit password change

master
Andrea Cimbalo 7 years ago
parent
commit
5849923a7a
6 changed files with 125 additions and 12 deletions
  1. +11
    -2
      lilikusers.py
  2. +7
    -2
      server.py
  3. +51
    -2
      static/index.html
  4. +30
    -0
      static/views/changePassword.html
  5. +11
    -4
      static/views/edit.html
  6. +15
    -2
      static/views/show.html

+ 11
- 2
lilikusers.py View File

@ -56,12 +56,17 @@ class LILiK_USER(object):
def to_dict(self):
return self.__dict__
@admin_connection_decorator
def diff(self, conn, new_lilik_user):
user_cn = utils.ldap_path('uid=%s'%self.uid, config.PEOPLE, config.DOMAIN)
return utils.DictDiffer(new_lilik_user, self.__dict__)
@admin_connection_decorator
def update(self, conn, new_lilik_user):
user_cn = utils.ldap_path('uid=%s'%self.uid, config.PEOPLE, config.DOMAIN)
diff = utils.DictDiffer(new_lilik_user, self.__dict__)
modifiers = {user_cn: {}}
if 'userPassword' in diff.added():
if 'userPassword' in diff.added() and new_lilik_user['userPassword']:
modifiers[user_cn]['userPassword'] = [(ldap3.MODIFY_REPLACE, [new_lilik_user['userPassword']])] #TODO add hash encryption?
for changed in diff.changed():
if changed == 'services':
@ -97,8 +102,12 @@ class LILiK_USER(object):
modifiers[user_cn]['givenname'] = [(ldap3.MODIFY_REPLACE, [firstname])]
modifiers[user_cn][changed] = [(ldap3.MODIFY_REPLACE, [new_lilik_user[changed]])]
for entry_cn, modifier in modifiers.items():
print(modifier.keys())
if modifier:
print(entry_cn, modifier)
if 'userPassword' in modifier.keys():
print(entry_cn, list(modifier.keys())[0], '****** (HIDDEN)')
else:
print(entry_cn, modifier)
conn.modify(entry_cn, modifier)
check_result(conn)
print(conn.result)


+ 7
- 2
server.py View File

@ -77,10 +77,15 @@ def get_user(user, user_name):
@app.route('/api/users/<user_name>', methods=['PUT'])
@requires_auth
@requires_admin_auth
@requires_same_user_or_admin_auth
def update_user(user, user_name):
new_lilik_user = request.get_json()
lilik_ldap.get_user(user_name).update(new_lilik_user)
user_to_edit = lilik_ldap.get_user(user_name)
diff = user_to_edit.diff(new_lilik_user)
is_permitted_self_changes = diff.changed() <= set(['cn']) and diff.removed() == set() and diff.added() <= set(['userPassword'])
print(user.uid)
if user.services['admin'] or is_permitted_self_changes:
user_to_edit.update(new_lilik_user)
return jsonify(lilik_ldap.get_user(user_name).to_dict())
@app.route('/api/users', methods=['POST'])


+ 51
- 2
static/index.html View File

@ -34,7 +34,7 @@
templateUrl: 'views/login.html',
hideMenus: true
}).when('/users/:ID', {
// controller: 'HomeController',
controller: 'EditController',
templateUrl: 'views/show.html'
}).when('/users/:ID/edit', {
controller: 'EditController',
@ -109,8 +109,9 @@
$location.path('/login');
}
});
}]).controller('EditController', ['$scope', '$routeParams', '$http', function($scope, $routeParams, $http) {
}]).controller('EditController', ['$scope', '$routeParams', '$http', '$mdDialog', function($scope, $routeParams, $http, $mdDialog) {
console.log($routeParams.ID);
$scope.password = {};
if ($routeParams.ID == $scope.globals.currentUser.username){
$scope.user = $scope.logged_user;
}else{
@ -120,12 +121,60 @@
});
}
$scope.save = function(){
console.log($scope.user);
if ($scope.password.new == $scope.password.confirm){
$scope.user.userPassword = $scope.password.new;
}
$http.put("/api/users/"+$routeParams.ID, $scope.user).then(function(response) {
console.log(response.data);
$scope.password = {};
$mdDialog.hide();
});
};
$scope.changePassword = function(ev) {
$scope.password = {};
// Appending dialog to document.body to cover sidenav in docs app
var confirm = {
clickOutsideToClose: true,
targetEvent: ev,
templateUrl: 'views/changePassword.html',
scope: $scope,
preserveScope: true,
}
$mdDialog.show(confirm).then(function(result) {
console.log(result);
// $http.post("/api/users", {uid: result}).then(function(response) {
// console.log(response.data);
// $rootScope.editUser(result);
// });
}, function(){});
};
$scope.closeDialog = function() {
$mdDialog.hide();
};
}]);;
app.directive('valueMatches', ['$parse', function ($parse) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ngModel) {
var originalModel = $parse(attrs.valueMatches),
secondModel = $parse(attrs.ngModel);
// Watch for changes to this input
scope.$watch(attrs.ngModel, function (newValue) {
ngModel.$setValidity(attrs.name, newValue === originalModel(scope));
});
// Watch for changes to the value-matches model's value
scope.$watch(attrs.valueMatches, function (newValue) {
ngModel.$setValidity(attrs.name, newValue === secondModel(scope));
});
}
};
}]);
// controller("myCtrl", function($scope, $http, authService) {
// $scope.$on('event:auth-loginRequired', function() {
// console.log(54546);


+ 30
- 0
static/views/changePassword.html View File

@ -0,0 +1,30 @@
<md-dialog md-theme="default" ng-class="dialog.css" class="_md md-default-theme md-transition-in">
<md-dialog-content class="md-dialog-content">
<h2>Change {{ user.uid }}'s password</h2>
<form name="newPasswordForm" role="form" ng-submit="newPasswordForm.$valid && ok()" novalidate>
<md-input-container class="md-block">
<label for="newPassword">New Password</label>
<input type="password" name="newPassword" ng-model="password.new"
ng-minlength="6" required />
<div class="help-block"
ng-show="newPasswordForm.newPassword.$dirty && newPasswordForm.newPassword.$invalid">
Please enter a new password, it must be at least 6 characters long.
</div>
</md-input-container>
<md-input-container class="md-block">
<label for="newPasswordConfirm">Confirm New Password</label>
<input type="password" name="newPasswordConfirm"
ng-model="password.confirm" ng-minlength="6"
value-matches="password.new" required />
<div class="help-block"
ng-show="newPasswordForm.newPasswordConfirm.$dirty && newPasswordForm.newPasswordConfirm.$invalid">
Please enter the same password again to confirm.
</div>
</md-input-container>
<md-dialog-actions>
<md-button ng-click="closeDialog()" class="md-primary">Cancel</md-button>
<md-button class="md-raised md-primary md-ink-ripple" ng-disabled="newPasswordForm.$invalid" ng-click="save()">Save</md-button>
</md-dialog-actions>
</form>
</md-dialog-content>
</md-dialog>

+ 11
- 4
static/views/edit.html View File

@ -5,10 +5,17 @@
</div>
</md-toolbar>
<md-content layout-padding>
<md-input-container class="md-block">
<label>Common name</label>
<input ng-model="user.cn" required autofocus>
</md-input-container>
<div layout="row" layout-align="space-between start">
<div>
<md-input-container class="md-block">
<label>Common name</label>
<input ng-model="user.cn" required autofocus>
</md-input-container>
</div>
<div>
<md-button class="md-raised" ng-click="changePassword()" ng-if="logged_user.services.admin">Change password</md-button>
</div>
</div>
<h3>Services</h3>
<div ng-repeat="(service, status) in user.services">
<md-checkbox aria-label="{{service}}" ng-model="user.services[service]">{{service}}</md-checkbox>


+ 15
- 2
static/views/show.html View File

@ -5,6 +5,19 @@
</div>
</md-toolbar>
<md-content layout-padding>
<div ng-repeat="(service, status) in logged_user.services" ng-if="status" ng-bind-html="getServiceDescription(service)"></div>
</md-content>
<div layout="row" layout-align="space-between start">
<div>
<!-- <md-input-container class="md-block">
<label>Common name</label>
<input ng-model="user.cn" required autofocus>
</md-input-container> -->
<div layout="column" layout-align="space-between start">
<div ng-repeat="(service, status) in logged_user.services" ng-if="status" ng-bind-html="getServiceDescription(service)"></div>
</div>
</div>
<div>
<md-button class="md-raised" ng-click="changePassword()">Change password</md-button>
</div>
</div>
</md-content>
</div>

Loading…
Cancel
Save