Author: ivol37 at gmail.com
Date: Thu Dec 23 09:05:21 2010
New Revision: 541

Log:
[AMDATU-222] Added member assignment functionality. Still TODO: basic 
authorization, multi-language support, more testing and bugfixing



Added:
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/select_role.js
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/RolesResource.java
Modified:
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/GroupsResource.java
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
   
trunk/amdatu-example/course-service/src/main/java/org/amdatu/example/course/service/service/ProfileDataProvider.java

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
      (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
      Thu Dec 23 09:05:21 2010
@@ -31,18 +31,20 @@
     <script type="text/javascript" 
src="/dashboard/static/js/lib/jquery-ui-1.8.2.custom.min.js"></script>
     <script type="text/javascript" 
src="${jsBaseUrl}/useradmin_rest.js"></script>
     <script type="text/javascript" src="${jsBaseUrl}/tabs.js"></script>
+    <script type="text/javascript" src="${jsBaseUrl}/select_role.js"></script>
     
     <p>
       <div id="container">
         <ul class="menu">
           <li id="users_tab" class="active">Users</li>
           <li id="groups_tab">Groups</li>
+          <li id="members_tab" style="display:none;visibility:hidden">Select 
role to add</li>
         </ul>
         
         <span class="clear"></span>
         
         <div class="content users_tab">
-          <div id="users"></div><br/>
+          <div id="user"></div><br/>
           
           <input type="button" value="Add user" id="add_user_button" 
onclick="javascript:showNewRole();"/>
 
@@ -51,6 +53,7 @@
               <table width="95%">
                 <tr><td>Username</td><td><input type="edit" id="user_name" 
value="" disabled="disabled" 
onkeyup="javascript:validateNonEmpty('user_name');"/></td></tr>
                 <tr><td id="password_label">New password</td><td><input 
type="password" id="password" value="" 
onkeyup="javascript:validateNonEmpty('password');"/></td></tr>
+                <tr><td valign="top">Implied roles</td><td 
id="implied_roles"></td></tr>
               </table>
               <input type="submit" id="user_save" value="Save" 
onclick="javascript:saveRole();" disabled="disabled"/>
               <input type="button" value="Cancel" 
onclick="javascript:showAddButton();"/>
@@ -60,7 +63,7 @@
         </div>
         
         <div class="content groups_tab">
-          <div id="groups"></div><br/>
+          <div id="group"></div><br/>
           
           <input type="button" value="Add group" id="add_group_button" 
onclick="javascript:showNewRole();"/>
           
@@ -68,6 +71,8 @@
             <legend id="group_details_legend">Details</legend>
               <table width="95%">
                 <tr><td>Group name</td><td><input type="edit" id="group_name" 
value="" disabled="disabled" 
onkeyup="javascript:validateNonEmpty('group_name');"/></td></tr>
+                <tr id="required_members_row"><td valign="top">Required 
members</td><td valign="top" id="required_members"></td></tr>
+                <tr id="basic_members_row"><td valign="top">Basic 
members</td><td valign="top" id="basic_members"></td></tr>
               </table>
               <input type="submit" id="group_save" value="Save" 
onclick="javascript:saveRole();" disabled="disabled"/>
               <input type="button" value="Cancel" 
onclick="javascript:showAddButton();"/>
@@ -76,6 +81,10 @@
           </fieldset>
           <br/>
         </div>
+        
+        <div class="content members_tab">
+          <div id="member"></div>
+        </div>
       </div>
     </p>
     
@@ -84,7 +93,8 @@
       var currentUrl;
       var currentUsersUrl;
       var currentGroupsUrl;
-      var id = "users";
+      var selectedRole;
+      var addToBasicMembers;
       
       // Callback function invoked when roles have been loaded
       function onRolesLoaded(response) {
@@ -97,16 +107,16 @@
         var links = jsonData["links"];
         for (i=0; i<links.length; i++) {
           if (links[i]["rel"] == "Start") {
-             var start = getImageLink("start.gif", links[i]["href"]);
+             var start = getNavigationLink("start.gif", links[i]["href"], 
"onRolesLoaded");
           } else if (links[i]["rel"] == "Prev") {
-             var prev = getImageLink("previous.gif", links[i]["href"]);
+             var prev = getNavigationLink("previous.gif", links[i]["href"], 
"onRolesLoaded");
           } else if (links[i]["rel"] == "Next") {
-             var next = getImageLink("next.gif", links[i]["href"]);
+             var next = getNavigationLink("next.gif", links[i]["href"], 
"onRolesLoaded");
           } else if (links[i]["rel"] == "End") {
-             var end = getImageLink("end.gif", links[i]["href"]);
+             var end = getNavigationLink("end.gif", links[i]["href"], 
"onRolesLoaded");
           } else if (links[i]["rel"] == "Alternate") {
              currentUrl = "${baseUrl}" + links[i]["href"];
-             if (id == "users") {
+             if (currentView == "user") {
               currentUsersUrl = currentUrl;
              } else {
               currentGroupsUrl = currentUrl;
@@ -117,14 +127,10 @@
         var html = "";
         
         // First add the table header
-        var roles = jsonData["roles"];
-        if (pageCount == 1) {
-          roles = new Array();
-          roles[0] = jsonData["roles"];
-        }
+        var roles = ensureArray(jsonData["roles"]);
         if (roles) {
           html += "<table class='stripeMe'>";
-          html += "<tr><th width='80%'>" + id + " name</th><th 
width='20%'>Delete</th></tr>";    
+          html += "<tr><th width='80%'>" + currentView + " name</th><th 
width='20%'>Delete</th></tr>";    
           for (i=0; i<roles.length; i++) {
             var role = roles[i];
             var link = role["link"].href;
@@ -143,10 +149,10 @@
         html += "<td>" + end + "</td></table>"; 
         
         var resultDiv;
-        if (currentView == "users") {
-          resultDiv = document.getElementById("users");
+        if (currentView == "user") {
+          resultDiv = document.getElementById("user");
         } else {
-          resultDiv = document.getElementById("groups");
+          resultDiv = document.getElementById("group");
         }
         resultDiv.innerHTML = html;
         
@@ -162,7 +168,31 @@
       function onRoleLoaded(response) {
         if (response.rc == 200) {
           var role = response.data["roles"];  
-          document.getElementById(id + '_name').value = role["name"];
+          document.getElementById(currentView + '_name').value = role["name"];
+          if (currentView == "user") {
+            var roles = ensureArray(role["impliedRoles"]);
+            var html = "<table><tbody>";
+            for (i=0; i<roles.length; i++) {
+              html += "<tr><td>" + roles[i] + "</td></tr>";
+            }
+            html += "</table>";
+            document.getElementById('implied_roles').innerHTML = html;
+          } else {
+            selectedRole = role["name"];
+            var requiredMembers = ensureArray(role["requiredMembers"]);
+            var html = "<table><tbody>";
+            html += renderMembers(requiredMembers);
+            html += "<tr><td><input type='button' value='Add' 
onclick='javascript:showAddMember(false);'/></td>";
+            html += "</table>";
+            document.getElementById('required_members').innerHTML = html;
+            
+            var basicMembers = ensureArray(role["basicMembers"]);
+            html = "<table><tbody>";
+            html += renderMembers(basicMembers);
+            html += "<tr><td><input type='button' value='Add' 
onclick='javascript:showAddMember(true);'/></td></tr>";
+            html += "</table>";
+            document.getElementById('basic_members').innerHTML = html;
+          }
           gadgets.window.adjustHeight();
          } else if (response.rc == 404) {
           showError("Role could not be found.");
@@ -171,6 +201,17 @@
         }   
       }
       
+      function renderMembers(members) {
+        var html = "";
+        for (i=0; i<members.length; i++) {
+          var name = members[i]["name"];
+          html += "<tr><td>" + name + "</td>";
+          var deleteMember = " onclick=\"javascript:confirmDeleteMember('" + 
escape(name) + "');\"";
+          html += "<td><a href='#'><img 
src='/gadget/useradmin/static/images/remove.gif'" + deleteMember + 
"/></td></tr>";
+        }
+        return html;
+      }
+      
       // Callback function invoked when the password of the user has been 
changed
       function onPasswordChanged(response) {
         if (response.rc == 200) {
@@ -208,11 +249,65 @@
         }    
       }
       
+      function onMemberAdded(response) {
+        if (response.rc == 200) {
+          // Role added successfully
+          showInfo('Member added successfully');
+          var url = escape("${restUrl}/groups/groups/" + 
encodeURIComponent(selectedRole));
+          loadRole(url, onRoleLoaded);
+          gadgets.window.adjustHeight();
+        } else if (response.rc == 304) {
+          showError("Member was already assigned to this role.");
+        } else {
+          showError(response.errors);
+        }    
+      }
+      
+      function onMemberRemoved(response) {
+        if (response.rc == 200) {
+          // Member removed successfully
+          showInfo('Member removed successfully');
+          var url = escape("${restUrl}/groups/groups/" + 
encodeURIComponent(selectedRole));
+          loadRole(url, onRoleLoaded);
+          gadgets.window.adjustHeight();
+        } else if (response.rc == 304) {
+          showError("Member was already removed from this group.");
+        } else {
+          showError(response.errors);
+        }    
+      }
+      
+      function showAddMember(addToBasic) {
+        // Show select role popup
+        addToBasicMembers = addToBasic;
+        show('members_tab');
+        switchToMembersTab();
+        switchToMembersView();
+      }
+      
+      function confirmDeleteMember(role) {
+        var removeFromRole = encodeURIComponent(selectedRole);
+        var removeRole = encodeURIComponent(unescape(role));
+        var url = "${baseUrl}/rest/services/groups/groups/" + removeFromRole + 
"/members/" + removeRole;
+        deleteMember(url, onMemberRemoved);
+      }
+      
+      function onAddMember(role) {
+        var addToRole = encodeURIComponent(selectedRole);
+        var addRole = encodeURIComponent(unescape(role));
+        if (addToBasicMembers) {
+          var url = "${baseUrl}/rest/services/groups/groups/" + addToRole + 
"/basicmembers/" + addRole;
+        } else {
+          var url = "${baseUrl}/rest/services/groups/groups/" + addToRole + 
"/requiredmembers/" + addRole;
+        }
+        addMember(url, onMemberAdded);
+      }
+      
       function saveRole() {
-        var method = document.getElementById(id + "_method").value;
-        var name = encodeURIComponent(document.getElementById(id + 
"_name").value);
+        var method = document.getElementById(currentView + "_method").value;
+        var name = encodeURIComponent(document.getElementById(currentView + 
"_name").value);
         
-        if (id == "users") {
+        if (currentView == "user") {
           var newpassword = document.getElementById('password').value
           var url = "${baseUrl}/rest/services/users/users/" + name;
           if (method == "update") {
@@ -229,14 +324,14 @@
       
       function validateNonEmpty(fieldId) {
         if (document.getElementById(fieldId).value != "") {
-          document.getElementById(id + "_save").disabled = "";
+          document.getElementById(currentView + "_save").disabled = "";
         } else {
-          document.getElementById(id + "_save").disabled = "disabled";
+          document.getElementById(currentView + "_save").disabled = "disabled";
         }
       }
       
-      function getImageLink(image, href) {
-        var result = "<a href='#'><img src='${imgBaseUrl}/" + image + "' 
onClick='javascript:loadRoles(\"${baseUrl}" + href + "\", 
onRolesLoaded)'/></a>";
+      function getNavigationLink(image, href, callback) {
+        var result = "<a href='#'><img src='${imgBaseUrl}/" + image + "' 
onClick='javascript:loadRoles(\"${baseUrl}" + href + "\", " + callback + 
")'/></a>";
         return result;
       }
       
@@ -253,57 +348,62 @@
       
       function showInfo(msg) {
         if (msg != "") {
-          document.getElementById(id + '_message').innerHTML = "<p><font 
color='green'>" + msg + "</font></p>";
+          document.getElementById(currentView + '_message').innerHTML = 
"<p><font color='green'>" + msg + "</font></p>";
         } else {
-          document.getElementById(id + '_message').innerHTML = "";
+          document.getElementById(currentView + '_message').innerHTML = "";
         }
         gadgets.window.adjustHeight();
       }
       
       function showError(msg) {
         if (msg != "") {
-          document.getElementById(id + '_message').innerHTML = "<p><font 
color='red'>" + msg + "</font></p>";
+          document.getElementById(currentView + '_message').innerHTML = 
"<p><font color='red'>" + msg + "</font></p>";
         } else {
-          document.getElementById(id + '_message').innerHTML = "";
+          document.getElementById(currentView + '_message').innerHTML = "";
         }
         gadgets.window.adjustHeight();
       }
       
       function showAddButton() {
-        show('add_' + id + '_button');
-        hide(id + '_details');
+        show('add_' + currentView + '_button');
+        hide(currentView + '_details');
         gadgets.window.adjustHeight();
       }
       
       function showNewRole() {
-        document.getElementById(id + '_details_legend').innerHTML = "New " + 
id;
-        document.getElementById(id + '_name').value = "";
-        document.getElementById(id + '_name').disabled = "";
-        document.getElementById(id + '_method').value = "add";
+        document.getElementById(currentView + '_details_legend').innerHTML = 
"New " + currentView;
+        document.getElementById(currentView + '_name').value = "";
+        document.getElementById(currentView + '_name').disabled = "";
+        document.getElementById(currentView + '_method').value = "add";
         
-        if (id == "users") {
+        if (currentView == "user") {
           document.getElementById('password_label').innerHTML = "Password";
           document.getElementById('password').value = "";
+        } else if (currentView == "group") {
+          hide('required_members_row');
+          hide('basic_members_row');
         }
-        
         showError("");
-        show(id + '_details');
-        hide('add_' + id + '_button');
+        show(currentView + '_details');
+        hide('add_' + currentView + '_button');
         gadgets.window.adjustHeight();
       }
       
       function showEditRole() {
-        document.getElementById(id + '_details_legend').innerHTML = id + " 
details";
-        document.getElementById(id + '_name').disabled = "disabled";
-        document.getElementById(id + '_method').value = "update";
+        document.getElementById(currentView + '_details_legend').innerHTML = 
currentView + " details";
+        document.getElementById(currentView + '_name').disabled = "disabled";
+        document.getElementById(currentView + '_method').value = "update";
  
-        if (id == "users") {
+        if (currentView == "user") {
           document.getElementById('password_label').innerHTML = "New password";
-        } 
+        } else if (currentView == "group") {
+          show('required_members_row');
+          show('basic_members_row');
+        }
         
         showError("");
-        show(id + '_details');
-        hide('add_' + id + '_button');
+        show(currentView + '_details');
+        hide('add_' + currentView + '_button');
         gadgets.window.adjustHeight();
       }
       
@@ -321,18 +421,33 @@
       
       function switchToUsersView() {
         restUrl = "${restUrl}/users/users?maxResults=5";
-        id = "user";
         currentUrl = currentUsersUrl;
         loadRoles(restUrl, onRolesLoaded);
       }
       
       function switchToGroupsView() {
         restUrl = "${restUrl}/groups/groups?maxResults=5";
-        id = "group";
         currentUrl = currentGroupsUrl;
         loadRoles(restUrl, onRolesLoaded);
       }
       
+      function switchToMembersView() {
+        restUrl = "${restUrl}/roles/roles?maxResults=10";
+        loadRoles(restUrl, onRolesLoadedForSelection);
+      }
+      
+      function ensureArray(input) {
+        // check if this result is an array
+        if (jQuery.isArray(input)) {
+          return input;
+        }
+        var result = [];
+        if (input != null) {
+          result.push(input);
+        }
+        return result;
+      }
+      
       $(document).ready(function(){
         loadRoles(restUrl, onRolesLoaded);
       });

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
  (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
  Thu Dec 23 09:05:21 2010
@@ -64,3 +64,7 @@
 .content.groups_tab{
   display: none;
 }
+
+.content.members_tab{
+  display: none;
+}

Added: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/select_role.js
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/select_role.js
     Thu Dec 23 09:05:21 2010
@@ -0,0 +1,54 @@
+function onRolesLoadedForSelection(response) {
+  var jsonData = response.data["searchresult"];
+  var pageStartIndex = jsonData["pageStartIndex"];
+  var pageEndIndex = jsonData["pageEndIndex"];
+  var resultCount = jsonData["resultCount"];
+  var pageCount = jsonData["pageCount"];
+
+  var links = jsonData["links"];
+  for (i=0; i<links.length; i++) {
+    if (links[i]["rel"] == "Start") {
+       var start = getNavigationLink("start.gif", links[i]["href"], 
"onRolesLoadedForSelection");
+    } else if (links[i]["rel"] == "Prev") {
+       var prev = getNavigationLink("previous.gif", links[i]["href"], 
"onRolesLoadedForSelection");
+    } else if (links[i]["rel"] == "Next") {
+       var next = getNavigationLink("next.gif", links[i]["href"], 
"onRolesLoadedForSelection");
+    } else if (links[i]["rel"] == "End") {
+       var end = getNavigationLink("end.gif", links[i]["href"], 
"onRolesLoadedForSelection");
+    } 
+  }
+
+  var html = "";
+  var roles = ensureArray(jsonData["roles"]);
+  if (roles) {
+    html += "<table class='stripeMe'>";
+    html += "<tr><th width='80%'>Role name</th><th>Type</th></tr>";    
+    for (i=0; i<roles.length; i++) {
+      var role = roles[i];
+      var selectRole = " onclick=\"javascript:selectRole('" + 
escape(role["name"]) + "');\"";
+      html += "<tr><td><a href='#'" + selectRole + ">" + role["name"] + 
"</a></td>";
+      var type;
+      if (role["type"] == 1) {
+        type = "User";
+      } else {
+         type = "Group";
+      }
+      html += "<td>" + type + "</td></tr>";
+    }
+    html += "</table></center></p>";
+    
+    html += "<p><center><table><tr>";
+    html += "<td>" + start + "</td>";
+    html += "<td>" + prev + "</td>";
+    html += "<td><center>Displaying results <b>" + pageStartIndex + "-" + 
pageEndIndex + "<b> of <b>" + resultCount + "</b></center></td>";
+    html += "<td>" + next + "</td>";
+    html += "<td>" + end + "</td></table>"; 
+  }
+ 
+  document.getElementById("member").innerHTML = html;
+}
+
+function selectRole(roleName) {
+  switchToGroupsTab();
+  onAddMember(roleName);
+}
\ No newline at end of file

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
    (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
    Thu Dec 23 09:05:21 2010
@@ -5,32 +5,64 @@
 //@license: Feel free to use it, but keep this credits please!          
 /***************************/
 
-var currentView = "users";
+var currentView = "user";
 
 $(document).ready(function(){
   $(".menu > li").click(function(e){
     switch(e.target.id){
       case "users_tab":
-        //change status & style menu
-        $("#users_tab").addClass("active");
-        $("#groups_tab").removeClass("active");
-        //display selected division, hide others
-        $("div.users_tab").fadeIn();
-        $("div.groups_tab").css("display", "none");
-        currentView = "users";
-        switchToUsersView();
+        if (currentView != "member") {
+          switchToUsersTab();
+          switchToUsersView();
+        }
       break;
       case "groups_tab":
-        //change status & style menu
-        $("#users_tab").removeClass("active");
-        $("#groups_tab").addClass("active");
-        //display selected division, hide others
-        $("div.groups_tab").fadeIn();
-        $("div.users_tab").css("display", "none");
-        currentView = "groups";
-        switchToGroupsView();
+        if (currentView != "member") {
+          switchToGroupsTab();
+          switchToGroupsView();
+        }
       break;
     }
     return false;
   });
-});
\ No newline at end of file
+});
+
+function switchToUsersTab() {
+  //change status & style menu
+  $("#users_tab").addClass("active");
+  $("#members_tab").removeClass("active");
+  $("#members_tab").css("display", "none");
+  $("#members_tab").css("visibility", "hidden");  
+  $("#groups_tab").removeClass("active");
+  //display selected division, hide others
+  $("div.users_tab").fadeIn();
+  $("div.groups_tab").css("display", "none");
+  $("div.members_tab").css("display", "none");
+  currentView = "user";
+  switchToUsersView();
+}
+
+function switchToGroupsTab() {
+  //change status & style menu
+  $("#users_tab").removeClass("active");
+  $("#members_tab").removeClass("active");
+  $("#members_tab").css("display", "none");
+  $("#members_tab").css("visibility", "hidden");
+  $("#groups_tab").addClass("active");
+  //display selected division, hide others
+  $("div.groups_tab").fadeIn();
+  $("div.users_tab").css("display", "none");
+  $("div.members_tab").css("display", "none");
+  currentView = "group";
+}
+
+function switchToMembersTab() {
+  $("#users_tab").removeClass("active");
+  $("#groups_tab").removeClass("active");
+  $("#members_tab").addClass("active");
+  //display selected division, hide others
+  $("div.members_tab").fadeIn();
+  $("div.users_tab").css("display", "none");
+  $("div.groups_tab").css("display", "none");
+  currentView = "member";
+}
\ No newline at end of file

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
  (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
  Thu Dec 23 09:05:21 2010
@@ -34,7 +34,23 @@
   url = addNoCache(url);  
   gadgets.io.makeRequest(url, callback, params);
 }
-      
+
+// Adds a new member
+ function addMember(url, callback) {
+  var params = {};
+  params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.PUT;
+  url = addNoCache(url);  
+  gadgets.io.makeRequest(url, callback, params);
+}
+
+// Removed a member
+function deleteMember(url, callback) {
+  var params = {};
+  params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.DELETE;
+  url = addNoCache(url);  
+  gadgets.io.makeRequest(url, callback, params);
+}
+
 // Deletes the specified role
 function deleteRole(url, callback) {
   var params = {};

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
  (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
  Thu Dec 23 09:05:21 2010
@@ -16,10 +16,9 @@
  */
 package org.amdatu.authorization.useradmin.rest.bean;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.ws.rs.core.UriBuilder;
 import javax.xml.bind.annotation.XmlAccessType;
@@ -29,18 +28,33 @@
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.amdatu.libraries.utilities.rest.AtomSyndicationLink;
+import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
 
 @SuppressWarnings("restriction")
 @XmlRootElement(name = "roles")
 @XmlAccessorType(XmlAccessType.NONE)
-public class RoleBean {    
+public class RoleBean {
     @XmlAttribute(name = "name")
     private String m_name;
 
+    @XmlAttribute(name = "type")
+    private int m_type;
+    
     @XmlElement(name = "link")
     private AtomSyndicationLink m_link;
 
+    @XmlElement(name = "impliedRoles")
+    private List<String> m_impliedRoles;
+
+    @XmlElement(name = "requiredMembers")
+    private List<RoleBean> m_requiredMembers;
+
+    @XmlElement(name = "basicMembers")
+    private List<RoleBean> m_basicMembers;
+
     public RoleBean() {
     }
 
@@ -52,6 +66,14 @@
         m_name = name;
     }
 
+    public int getType() {
+        return m_type;
+    }
+
+    public void setType(int type) {
+        m_type = type;
+    }
+
     public AtomSyndicationLink getLink() {
         return m_link;
     }
@@ -60,14 +82,72 @@
         m_link = link;
     }
 
-    public static RoleBean fromRole(Role role) throws URISyntaxException {
+    public List<String> getImpliedRoles() {
+        return m_impliedRoles;
+    }
+
+    public void setImpliedRoles(List<String> impliedRoles) {
+        m_impliedRoles = impliedRoles;
+    }
+
+    public void setImpliedRoles(String[] impliedRoles) {
+        m_impliedRoles = new ArrayList<String>();
+        for (String impliedRole : impliedRoles) {
+            m_impliedRoles.add(impliedRole);
+        }
+    }
+
+    public List<RoleBean> getRequiredMembers() {
+        return m_requiredMembers;
+    }
+
+    public void setRequiredMembers(List<RoleBean> requiredMembers) {
+        m_requiredMembers = requiredMembers;
+    }
+
+    public List<RoleBean> getBasicMembers() {
+        return m_basicMembers;
+    }
+
+    public void setBasicMembers(List<RoleBean> basicMembers) {
+        m_basicMembers = basicMembers;
+    }
+
+    public static RoleBean fromRole(Role role, UserAdmin userAdmin) throws 
URISyntaxException {
+        return fromRole(role, userAdmin, true);
+    }
+
+    public static RoleBean fromRole(Role role, UserAdmin userAdmin, boolean 
loadMembers) throws URISyntaxException {
         RoleBean roleBean = new RoleBean();
         String name = role.getName();
         roleBean.setName(name);
+        roleBean.setType(role.getType());
         String href = "/rest/services/";
         if (role.getType() == Role.USER) {
+            String[] impliedRoles = userAdmin.getAuthorization((User) 
role).getRoles();
+            roleBean.setImpliedRoles(impliedRoles);
             href += "users/users/" + name;
-        } else {
+        }
+        else {
+            if (loadMembers) {
+                Role[] requiredRoles = ((Group) role).getRequiredMembers();
+                List<RoleBean> requiredMembers = new ArrayList<RoleBean>();
+                if (requiredRoles != null) {
+                    for (Role member : requiredRoles) {
+                        requiredMembers.add(fromRole(member, userAdmin, 
false));
+                    }
+                }
+                roleBean.setRequiredMembers(requiredMembers);
+
+                Role[] basicRoles = ((Group) role).getMembers();
+                List<RoleBean> basicMembers = new ArrayList<RoleBean>();
+                if (basicRoles != null) {
+                    for (Role member : basicRoles) {
+                        basicMembers.add(fromRole(member, userAdmin, false));
+                    }
+                }
+                roleBean.setBasicMembers(basicMembers);
+            }
             href += "groups/groups/" + name;
         }
         // Use JAX-RS URI builder to properly encode the href

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
  (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
  Thu Dec 23 09:05:21 2010
@@ -26,6 +26,7 @@
 
 import org.amdatu.libraries.utilities.rest.AtomSyndicationLink;
 import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.UserAdmin;
 
 @SuppressWarnings("restriction")
 @XmlRootElement(name = "searchresult")
@@ -109,9 +110,9 @@
         m_roles = users;
     }
     
-    public void addRoles(List<Role> roles) throws URISyntaxException {
+    public void addRoles(List<Role> roles, UserAdmin userAdmin) throws 
URISyntaxException {
         for (Role role : roles) {
-            RoleBean roleBean = RoleBean.fromRole(role);
+            RoleBean roleBean = RoleBean.fromRole(role, userAdmin);
             m_roles.add(roleBean);
         }
     }

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
 (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/osgi/Activator.java
 Thu Dec 23 09:05:21 2010
@@ -17,6 +17,7 @@
 package org.amdatu.authorization.useradmin.rest.osgi;
 
 import org.amdatu.authorization.useradmin.rest.service.GroupsResource;
+import org.amdatu.authorization.useradmin.rest.service.RolesResource;
 import org.amdatu.authorization.useradmin.rest.service.UsersResource;
 import org.amdatu.libraries.utilities.osgi.ServiceDependentActivator;
 import org.amdatu.web.rest.jaxrs.JaxRsSpi;
@@ -52,6 +53,13 @@
             .setImplementation(GroupsResource.class)
             
.add(createServiceDependency().setService(LogService.class).setRequired(true))
             
.add(createServiceDependency().setService(UserAdmin.class).setRequired(true)));
+        
+        // Create the groups resource service and register it as REST service
+        manager.add(createComponent()
+            .setInterface(RESTService.class.getName(), null)
+            .setImplementation(RolesResource.class)
+            
.add(createServiceDependency().setService(LogService.class).setRequired(true))
+            
.add(createServiceDependency().setService(UserAdmin.class).setRequired(true))); 
       
     }
 
     @Override

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/GroupsResource.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/GroupsResource.java
 (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/GroupsResource.java
 Thu Dec 23 09:05:21 2010
@@ -47,13 +47,6 @@
  */
 @Path("groups")
 public class GroupsResource extends ResourceBase implements RESTService {
-    // Disable HTTP caching in this REST interface
-    private static CacheControl m_cacheControl;
-    static {
-        m_cacheControl = new CacheControl();
-        m_cacheControl.setNoCache(true);
-    }
-    
     /**
      * This method can be used to check the availability of the Groups 
management service.
      * @return The text "UserAdmin Groups management service online"

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
   (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
   Thu Dec 23 09:05:21 2010
@@ -30,16 +30,15 @@
 import org.amdatu.authorization.useradmin.rest.bean.RoleBean;
 import org.amdatu.authorization.useradmin.rest.bean.SearchResultBean;
 import org.amdatu.libraries.utilities.rest.AtomSyndicationLink;
-import org.json.JSONException;
+import org.amdatu.web.rest.jaxrs.RESTService;
 import org.json.JSONObject;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.log.LogService;
-import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
 
-abstract class ResourceBase {
+abstract class ResourceBase implements RESTService {
     // Service dependencies injected by the depedency manager
     protected volatile LogService m_logService;
     protected volatile UserAdmin m_userAdmin;
@@ -78,7 +77,9 @@
             List<Role> filteredRoles = new ArrayList<Role>();
             if (roles != null) {
                 for (Role role : roles) {
-                    if (role.getType() == roleType) {
+                    if (roleType == Role.ROLE) {
+                        filteredRoles.add(role);
+                    } else if (role.getType() == roleType) {
                         if (filter == null || role.getName().matches("?i:.*" + 
filter + ".*")) {
                             filteredRoles.add(role);
                         }
@@ -104,7 +105,7 @@
             }
 
             SearchResultBean result = new SearchResultBean();
-            result.addRoles(roleRange);
+            result.addRoles(roleRange, m_userAdmin);
 
             // Calculate paging
             Paging paging = new Paging();
@@ -173,7 +174,7 @@
         Role role = m_userAdmin.getRole(name);
         if (role != null && role.getType() == roleType) {
             try {
-                RoleBean user = RoleBean.fromRole(role);
+                RoleBean user = RoleBean.fromRole(role, m_userAdmin);
                 return Response.ok(user).cacheControl(m_cacheControl).build();
             }
             catch (URISyntaxException e) {
@@ -235,35 +236,6 @@
         }
     }
 
-    private JSONObject getJSON(Role role) throws JSONException {
-        JSONObject jsonRole = new JSONObject();
-        jsonRole.put("name", role.getName());
-        jsonRole.put("properties", role.getProperties());
-
-        if (role.getType() == Role.GROUP) {
-            Role[] members = ((Group) role).getMembers();
-            JSONObject jsonMembers = new JSONObject();
-            if (members != null) {
-                for (Role member : members) {
-                    JSONObject jsonMember = getJSON(member);
-                    jsonMember.append("member", jsonMember);
-                }
-            }
-            jsonRole.put("members", jsonMembers);
-
-            Role[] reqMembers = ((Group) role).getRequiredMembers();
-            JSONObject jsonReqMembers = new JSONObject();
-            if (reqMembers != null) {
-                for (Role member : reqMembers) {
-                    JSONObject jsonMember = getJSON(member);
-                    jsonMember.append("member", jsonMember);
-                }
-            }
-            jsonRole.put("requiredMembers", jsonReqMembers);
-        }
-        return jsonRole;
-    }
-
     protected Response buildOK() {
         return Response.ok().cacheControl(m_cacheControl).build();
     }
@@ -313,7 +285,7 @@
             pageCount = pageResults;
             pageMax = maxResults;
             pageStartIndex = pageResults > 0 ? Math.max(1, currentStartIndex) 
: 0;
-            pageEndIndex = pageStartIndex + (pageResults - 1);
+            pageEndIndex = Math.max(0, pageStartIndex + (pageResults - 1));
 
             // Calculate first page
             firstStartIndex = pageResults > 0 ? 1 : 0;

Added: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/RolesResource.java
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/RolesResource.java
  Thu Dec 23 09:05:21 2010
@@ -0,0 +1,73 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    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, either version 3 of the License, or
+    (at your option) any later version.
+
+    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, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.authorization.useradmin.rest.service;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.osgi.service.useradmin.Role;
+
+ at Path("roles")
+public class RolesResource extends ResourceBase{
+    /**
+     * Returns all users that match the specified filter options. This method 
can be invoked by making the following
+     * REST call:<code><pre>
+     * GET 
/rest/services/users/users?filter={filter}&sortOrder={sortOrder}&startIndex={startIndex}&maxResults={maxResults}
+     * </pre></code> For available path and query parameters, see below.
+     * @param filter Filter that the name of the user must match. A user name 
is considered to match the specified
+     *            filter if the filter equals the user name or the filter is a 
substring of the user name.
+     * @param sortOrder 'ascending' to return results in ascending order or 
'descending' to return results in descending
+     *            order.
+     * @param startIndex The index of the first result to return (default is 
1).
+     * @param maxResults The maximum amount of results to return (default is 
50).
+     * @return a 400 response with this JSON string containing the results in 
case the call was successful: <code><pre>
+     * {
+     *   "totalCount":1,             => Total amount of available results for 
this query, independent of the values of startIndex and maxResults
+     *   "resultCount":1,            => Amount of results returned, depending 
on startIndex and maxResults
+     *   "maxResults":50             => The maximum amount of results returned 
in the result (if provided as request parameter, this value is the same)
+     *   "startIndex":1,             => Index of the first search result 
returned (if provided as request parameter, this value is the same)
+     *   "endIndex":1,               => Index of the last search result 
returned
+     *   "firstStartIndex":1,        => Index of the first available result 
for this query
+     *   "lastStartIndex":1,         => Last index of available results for 
this query (i.e. if there are 243 results available and maxResults is 50, this 
value equals 201)
+     *   "entry":[                   => Result entries
+     *    {
+     *      "name":"Administrator",  => Name of the user
+     *      "properties":{}          => Properties of the user
+     *    }]
+     * }
+     * </pre></code> a 500 response in case any exception occurred.
+     */    
+    @GET
+    @Produces({MediaType.APPLICATION_JSON})
+    public Response getUsers(
+            @QueryParam("filter") final String filter,
+            @QueryParam("sortOrder") final String sortOrder,
+            @DefaultValue("1") @QueryParam("startIndex") final int startIndex,
+            @DefaultValue("50") @QueryParam("maxResults") final int 
maxResults) {
+        return super.getRoles(filter, sortOrder, startIndex, maxResults, 
Role.ROLE);
+    }
+
+    @Override
+    protected String getBaseUrl() {
+        return "/rest/services/roles/roles";
+    }
+}

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
  (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/UsersResource.java
  Thu Dec 23 09:05:21 2010
@@ -43,7 +43,7 @@
  * @author ivol
  */
 @Path("users")
-public class UsersResource extends ResourceBase implements RESTService  {    
+public class UsersResource extends ResourceBase {    
     /**
      * Returns all users that match the specified filter options. This method 
can be invoked by making the following
      * REST call:<code><pre>

Modified: 
trunk/amdatu-example/course-service/src/main/java/org/amdatu/example/course/service/service/ProfileDataProvider.java
==============================================================================
--- 
trunk/amdatu-example/course-service/src/main/java/org/amdatu/example/course/service/service/ProfileDataProvider.java
        (original)
+++ 
trunk/amdatu-example/course-service/src/main/java/org/amdatu/example/course/service/service/ProfileDataProvider.java
        Thu Dec 23 09:05:21 2010
@@ -22,6 +22,7 @@
 import org.apache.shindig.social.core.model.NameImpl;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
@@ -71,6 +72,21 @@
                 createTestPerson("elisad", "Elisa Davis", 15, new 
String[]{"melissad"});
                 createTestPerson("marior", "Mario Rossi", 54, new 
String[]{"johnd"});
                 createTestPerson("maijam", "Maija Meik\u00e4l\u00e4inen", 37, 
new String[]{"janed"});
+                
+                // Now create roles 'Teacher' and 'Student' and assign basic 
members
+                Group teacher = (Group) m_userAdmin.createRole("Teacher", 
Role.GROUP);
+                teacher.addMember(m_userAdmin.getRole("marior"));
+                teacher.addMember(m_userAdmin.getRole("maijam"));
+                
+                Group student = (Group) m_userAdmin.createRole("Student", 
Role.GROUP);
+                student.addMember(m_userAdmin.getRole("elisad"));
+                student.addMember(m_userAdmin.getRole("melissad"));
+                student.addMember(m_userAdmin.getRole("tedb"));
+                student.addMember(m_userAdmin.getRole("georged"));
+                
+                Group parent = (Group) m_userAdmin.createRole("Parent", 
Role.GROUP);
+                parent.addMember(m_userAdmin.getRole("janed"));
+                parent.addMember(m_userAdmin.getRole("johnd"));
             } else {
                 m_logService.log(LogService.LOG_DEBUG, "Test users already 
exist, none created");
             }

Reply via email to