Introduce CMS User Admin (not yet wired)
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 10 Feb 2015 10:38:36 +0000 (10:38 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 10 Feb 2015 10:38:36 +0000 (10:38 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@7774 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.cms/src/org/argeo/cms/internal/useradmin/AbstractJcrUser.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrEnduser.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrGroup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrRole.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java [new file with mode: 0644]

diff --git a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/AbstractJcrUser.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/AbstractJcrUser.java
new file mode 100644 (file)
index 0000000..5ca3b39
--- /dev/null
@@ -0,0 +1,21 @@
+package org.argeo.cms.internal.useradmin;
+
+import java.util.Dictionary;
+
+import org.osgi.service.useradmin.User;
+
+abstract class AbstractJcrUser extends JcrRole implements User {
+
+       @Override
+       public Dictionary<String, Object> getCredentials() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public boolean hasCredential(String key, Object value) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrEnduser.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrEnduser.java
new file mode 100644 (file)
index 0000000..8b5baf4
--- /dev/null
@@ -0,0 +1,16 @@
+package org.argeo.cms.internal.useradmin;
+
+import org.springframework.security.core.userdetails.UserDetails;
+
+class JcrEnduser extends AbstractJcrUser {
+       private final UserDetails userDetails;
+
+       public JcrEnduser(UserDetails userDetails) {
+               this.userDetails = userDetails;
+       }
+
+       UserDetails getUserDetails() {
+               return userDetails;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrGroup.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrGroup.java
new file mode 100644 (file)
index 0000000..ffbeb13
--- /dev/null
@@ -0,0 +1,40 @@
+package org.argeo.cms.internal.useradmin;
+
+import org.osgi.service.useradmin.Group;
+import org.osgi.service.useradmin.Role;
+
+class JcrGroup extends AbstractJcrUser implements Group {
+       public JcrGroup(String name) {
+       }
+
+       @Override
+       public boolean addMember(Role role) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean addRequiredMember(Role role) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean removeMember(Role role) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public Role[] getMembers() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Role[] getRequiredMembers() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrRole.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrRole.java
new file mode 100644 (file)
index 0000000..5bd0d57
--- /dev/null
@@ -0,0 +1,27 @@
+package org.argeo.cms.internal.useradmin;
+
+import java.util.Dictionary;
+
+import org.osgi.service.useradmin.Role;
+
+class JcrRole implements Role {
+
+       @Override
+       public String getName() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public int getType() {
+               // TODO Auto-generated method stub
+               return 0;
+       }
+
+       @Override
+       public Dictionary<String, Object> getProperties() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java b/org.argeo.cms/src/org/argeo/cms/internal/useradmin/JcrUserAdmin.java
new file mode 100644 (file)
index 0000000..4ee4312
--- /dev/null
@@ -0,0 +1,158 @@
+package org.argeo.cms.internal.useradmin;
+
+import static org.argeo.jcr.ArgeoJcrConstants.ALIAS_NODE;
+import static org.argeo.jcr.ArgeoJcrConstants.JCR_REPOSITORY_ALIAS;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.argeo.security.jcr.SimpleJcrSecurityModel;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+import org.osgi.service.useradmin.UserAdminEvent;
+import org.osgi.service.useradmin.UserAdminListener;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+public class JcrUserAdmin implements UserAdmin {
+       private final BundleContext bundleContext;
+       private UserAdminService userAdminService;
+
+       private final JcrSecurityModel jcrSecurityModel = new SimpleJcrSecurityModel();
+       private final Session session;
+
+       public JcrUserAdmin(BundleContext bundleContext) {
+               try {
+                       this.bundleContext = bundleContext;
+
+                       ServiceReference<Repository> nodeRepo = bundleContext
+                                       .getServiceReferences(Repository.class,
+                                                       "(" + JCR_REPOSITORY_ALIAS + "=" + ALIAS_NODE + ")")
+                                       .iterator().next();
+                       this.session = bundleContext.getService(nodeRepo).login();
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot initialize user admin", e);
+               }
+       }
+
+       @Override
+       public Role createRole(String name, int type) {
+               try {
+                       if (Role.USER == type) {
+                               Node userProfile = jcrSecurityModel.sync(session, name, null);
+                               session.getWorkspace().getVersionManager()
+                                               .checkout(userProfile.getPath());
+                               String password = "";
+                               // TODO add roles
+                               JcrUserDetails userDetails = new JcrUserDetails(userProfile,
+                                               password, new ArrayList<GrantedAuthority>());
+                               session.save();
+                               session.getWorkspace().getVersionManager()
+                                               .checkin(userProfile.getPath());
+                               userAdminService().createUser(userDetails);
+                               return new JcrEnduser(userDetails);
+                       } else if (Role.GROUP == type) {
+                               userAdminService().newRole(name);
+                               return new JcrGroup(name);
+                       } else {
+                               throw new ArgeoException("Unsupported role type " + type);
+                       }
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot create role " + name);
+               }
+       }
+
+       @Override
+       public boolean removeRole(String name) {
+               Role role = getRole(name);
+               if (role == null)
+                       return false;
+               if (role instanceof JcrEnduser)
+                       userAdminService().deleteUser(role.getName());
+               else if (role instanceof JcrGroup)
+                       userAdminService().deleteRole(role.getName());
+               else
+                       return false;
+               return true;
+       }
+
+       @Override
+       public Role getRole(String name) {
+               if (userAdminService().listEditableRoles().contains(name))
+                       return new JcrGroup(name);
+               try {
+                       UserDetails userDetails = userAdminService().loadUserByUsername(
+                                       name);
+                       return new JcrEnduser(userDetails);
+               } catch (UsernameNotFoundException e) {
+                       return null;
+               }
+       }
+
+       @Override
+       public Role[] getRoles(String filter) throws InvalidSyntaxException {
+               if (filter != null)
+                       throw new ArgeoException("Filtering not yet implemented");
+               List<String> roles = new ArrayList<String>(userAdminService()
+                               .listEditableRoles());
+               List<String> users = new ArrayList<String>(userAdminService()
+                               .listUsers());
+               Role[] res = new Role[users.size() + roles.size()];
+               for (int i = 0; i < roles.size(); i++)
+                       res[i] = new JcrGroup(roles.get(i));
+               for (int i = 0; i < users.size(); i++)
+                       res[roles.size() + i] = new JcrEnduser(userAdminService()
+                                       .loadUserByUsername(users.get(i)));
+               return res;
+       }
+
+       @Override
+       public User getUser(String key, String value) {
+               throw new ArgeoException("Property based search not yet implemented");
+       }
+
+       @Override
+       public Authorization getAuthorization(User user) {
+               return null;
+       }
+
+       private synchronized UserAdminService userAdminService() {
+               return userAdminService;
+       }
+
+       public void setUserAdminService(UserAdminService userAdminService) {
+               this.userAdminService = userAdminService;
+       }
+
+       protected synchronized void notifyEvent(UserAdminEvent event) {
+               try {
+                       Collection<ServiceReference<UserAdminListener>> sr = bundleContext
+                                       .getServiceReferences(UserAdminListener.class, null);
+                       for (Iterator<ServiceReference<UserAdminListener>> it = sr
+                                       .iterator(); it.hasNext();) {
+                               UserAdminListener listener = bundleContext
+                                               .getService(it.next());
+                               listener.roleChanged(event);
+                       }
+               } catch (InvalidSyntaxException e) {
+                       throw new ArgeoException("Cannot notify listeners", e);
+               }
+       }
+}