keycloak-aplcache

Details

diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js
index 0d5f4cd..6b3ac2f 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js
@@ -136,6 +136,39 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, $locatio
 
     $scope.changed = false; // $scope.create;
 
+    // ID - Name map for required actions. IDs are enum names.
+    var userReqActionList = [
+        {id: "VERIFY_EMAIL", text: "Verify Email"},
+        {id: "UPDATE_PROFILE", text: "Update Profile"},
+        {id: "CONFIGURE_TOTP", text: "Configure Totp"},
+        {id: "UPDATE_PASSWORD", text: "Update Password"}
+    ];
+
+    // Options for the req actions tag selector
+    $scope.userReqActionsOptions = {
+        'multiple' : true,
+        'tags' : userReqActionList
+    };
+
+    // Model for the req actions tag selector
+    $scope.userActions = [];
+    for (var i = 0; i < userReqActionList.length; i++){
+        var action = userReqActionList[i];
+
+        if ($scope.user.requiredActions.indexOf(action.id) > -1){
+            $scope.userActions.push({id: action.id, text: action.text});
+        }
+    }
+
+    // Watching ui-select2 model to properly format the req actions for user
+    $scope.$watch("userActions", function(newValue, oldValue) {
+        $scope.user.requiredActions = [];
+        for (var i=0; i < newValue.length; i++){
+            var action = newValue[i];
+            $scope.user.requiredActions.push(action.id);
+        }
+    });
+
     $scope.$watch('user', function() {
         if (!angular.equals($scope.user, user)) {
             $scope.changed = true;
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
index fec6872..5505366 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
@@ -78,7 +78,13 @@
                             <label for="emailVerified" class="control-label">Email verified</label>
                             <input ng-model="user.emailVerified" name="emailVerified" id="emailVerified" onoffswitch />
                         </div>
+                        <div class="form-group clearfix">
+                            <label for="reqActions" class="control-label two-lines">Required User Actions</label>
 
+                            <div class="controls">
+                                <input type="text" ui-select2="userReqActionsOptions" ng-model="userActions" id="reqActions"/>
+                            </div>
+                        </div>
                     </fieldset>
                     <div class="form-actions" data-ng-show="create">
                         <button type="submit" data-ng-click="save()" class="primary" data-ng-show="changed">Save
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 7c49e9d..347aca8 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -390,6 +390,14 @@ public class RealmManager {
         rep.setEnabled(user.isEnabled());
         rep.setEmailVerified(user.isEmailVerified());
         rep.setTotp(user.isTotp());
+
+        List<String> reqActions = new ArrayList<String>();
+        for (RequiredAction ra : user.getRequiredActions()){
+            reqActions.add(ra.name());
+        }
+
+        rep.setRequiredActions(reqActions);
+
         if (user.getAttributes() != null && !user.getAttributes().isEmpty()) {
             Map<String, String> attrs = new HashMap<String, String>();
             attrs.putAll(user.getAttributes());
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index b81480d..2901c9c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -64,19 +64,7 @@ public class UsersResource {
         if (user == null) {
             throw new NotFoundException();
         }
-        user.setEmail(rep.getEmail());
-        user.setFirstName(rep.getFirstName());
-        user.setLastName(rep.getLastName());
-
-        user.setEnabled(rep.isEnabled());
-        user.setTotp(rep.isTotp());
-        user.setEmailVerified(rep.isEmailVerified());
-
-        if (rep.getAttributes() != null) {
-            for (Map.Entry<String, String> attr : rep.getAttributes().entrySet()) {
-                user.setAttribute(attr.getKey(), attr.getValue());
-            }
-        }
+        updateUserFromRep(user, rep);
     }
 
     @POST
@@ -89,6 +77,13 @@ public class UsersResource {
         if (user == null) {
             throw new NotFoundException();
         }
+
+        updateUserFromRep(user, rep);
+
+        return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getLoginName()).build()).build();
+    }
+
+    private void updateUserFromRep(UserModel user, UserRepresentation rep){
         user.setEmail(rep.getEmail());
         user.setFirstName(rep.getFirstName());
         user.setLastName(rep.getLastName());
@@ -97,12 +92,21 @@ public class UsersResource {
         user.setTotp(rep.isTotp());
         user.setEmailVerified(rep.isEmailVerified());
 
+        List<String> reqActions = rep.getRequiredActions();
+
+        for(UserModel.RequiredAction ra : UserModel.RequiredAction.values()){
+            if (reqActions.contains(ra.name())) {
+                user.addRequiredAction(ra);
+            } else {
+                user.removeRequiredAction(ra);
+            }
+        }
+
         if (rep.getAttributes() != null) {
             for (Map.Entry<String, String> attr : rep.getAttributes().entrySet()) {
                 user.setAttribute(attr.getKey(), attr.getValue());
             }
         }
-        return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getLoginName()).build()).build();
     }
 
     @Path("{username}")