Set all required objectClass attributes when adding an entry to LDAP. Also consistent...
[pithos] / src / gr / ebs / gss / server / ejb / ExternalAPIBean.java
index 906eb76..0cb2971 100644 (file)
@@ -31,6 +31,7 @@ import gr.ebs.gss.server.domain.FileTag;
 import gr.ebs.gss.server.domain.FileUploadStatus;
 import gr.ebs.gss.server.domain.Folder;
 import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.Invitation;
 import gr.ebs.gss.server.domain.Nonce;
 import gr.ebs.gss.server.domain.Permission;
 import gr.ebs.gss.server.domain.User;
@@ -106,6 +107,12 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
+import com.novell.ldap.LDAPAttribute;
+import com.novell.ldap.LDAPAttributeSet;
+import com.novell.ldap.LDAPConnection;
+import com.novell.ldap.LDAPEntry;
+import com.novell.ldap.LDAPException;
+
 /**
  * The concrete implementation of the ExternalAPI interface.
  *
@@ -141,12 +148,15 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
         */
        private static Random random = new Random();
 
-       private void touchParentFolders(Folder folder, User modifiedBy, Date modificationDate) {
+       /**
+        * Mark the folder and all of its parent folders as modified from the specified user.
+        */
+       private void touchParentFolders(Folder folder, User user, Date date) {
                Folder f = folder;
-               while (f!=null) {
+               while (f != null) {
                        AuditInfo ai = f.getAuditInfo();
-                       ai.setModifiedBy(modifiedBy);
-                       ai.setModificationDate(modificationDate);
+                       ai.setModifiedBy(user);
+                       ai.setModificationDate(date);
                        f.setAuditInfo(ai);
                        f = f.getParent();
                }
@@ -160,11 +170,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                return folder.getDTO();
        }
 
-       /*
-        * (non-Javadoc)
-        *
-        * @see gr.ebs.gss.server.ejb.ExternalAPI#getFolder(java.lang.Long)
-        */
+       @Override
        public FolderDTO getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
@@ -681,11 +687,12 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                if(permissions != null && !permissions.isEmpty() &&     !file.hasModifyACLPermission(user))
                        throw new InsufficientPermissionsException("User " + user.getId() +     " cannot update the permissions on file " +     file.getName() + "(" + file.getId() + ")");
 
-               if (name != null)
+               if (name != null) {
                        // Do plain check for file already exists.
                        // Extreme concurrency case should be caught by constraint violation later.
                        if (dao.existsFolderOrFile(parent.getId(), name)) throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
                        file.setName(name);
+               }
 
                if (modificationDate != null)
                        file.getAuditInfo().setModificationDate(modificationDate);
@@ -1221,7 +1228,7 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public void moveFolderToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
+       public void moveFolderToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
                if (userId == null)
                        throw new ObjectNotFoundException("No user specified");
                if (ownerId == null)
@@ -1239,16 +1246,62 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public void moveFolder(Long userId, Long folderId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
-               // TODO Simple Move and delete of original folder, in production
-               // scenario we must first check individual files and folders permissions
-               copyFolderStructure(userId, folderId, destId, destName);
-               deleteFolder(userId, folderId);
+       public void moveFolder(Long userId, Long folderId, Long destId, String destName)
+                       throws ObjectNotFoundException, InsufficientPermissionsException,
+                       QuotaExceededException {
+               Folder source = dao.getEntityById(Folder.class, folderId);
+               Folder destination = dao.getEntityById(Folder.class, destId);
+               User user = dao.getEntityById(User.class, userId);
+               User sourceOwner = source.getOwner();
+               User destinationOwner = destination.getOwner();
+               // Do not move trashed folders and contents.
+               if (source.isDeleted())
+                       return;
+               // Check permissions.
+               if (!destination.hasWritePermission(user)
+                               || !source.hasReadPermission(user)
+                               || !source.hasWritePermission(user))
+                       throw new InsufficientPermissionsException("You don't have the " +
+                                       "necessary permissions");
+               // Use the same timestamp for all subsequent modifications to make
+               // changes appear simultaneous.
+               Date now = new Date();
+               // If source and destination are not in the same user's namespace,
+               // change owners and check quota.
+               if (!sourceOwner.equals(destinationOwner)) {
+                       changeOwner(source, destinationOwner, user, now);
+                       if (getQuotaLeft(destinationOwner.getId()) < 0)
+                               throw new QuotaExceededException("Not enough free space " +
+                                               "available in destination folder");
+               }
+               // Perform the move.
+               Folder oldParent = source.getParent();
+               oldParent.removeSubfolder(source);
+               destination.addSubfolder(source);
+               // Mark the former parent and destination trees upwards as modified.
+               touchParentFolders(oldParent, user, now);
+               touchParentFolders(source, user, now);
        }
 
-       /* (non-Javadoc)
-        * @see gr.ebs.gss.server.ejb.ExternalAPI#getDeletedFiles(java.lang.Long)
+       /**
+        * Recursively change the owner of the specified folder and all of its
+        * contents to the specified owner. Also mark them all as modified with the
+        * specified modifier and modificationDate.
         */
+       private void changeOwner(Folder folder, User owner, User modifier, Date modificationDate) {
+               for (FileHeader file: folder.getFiles()) {
+                       file.setOwner(owner);
+                       file.getAuditInfo().setModificationDate(modificationDate);
+                       file.getAuditInfo().setModifiedBy(modifier);
+               }
+               for (Folder sub: folder.getSubfolders())
+                       changeOwner(sub, owner, modifier, modificationDate);
+               folder.setOwner(owner);
+               folder.getAuditInfo().setModificationDate(modificationDate);
+               folder.getAuditInfo().setModifiedBy(modifier);
+       }
+
+       @Override
        public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException {
                // Validate.
                if (userId == null)
@@ -1356,7 +1409,8 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public User createUser(String username, String name, String mail) throws ObjectNotFoundException {
+       public User createUser(String username, String name, String mail,
+                               String idp, String idpid) throws ObjectNotFoundException {
                if (username == null)
                        throw new ObjectNotFoundException("No username specified");
                if (name == null)
@@ -1366,6 +1420,8 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                user.setUsername(username);
                user.setName(name);
                user.setEmail(mail);
+               user.setIdentityProvider(idp);
+               user.setIdentityProviderId(idpid);
                Date now = new Date();
                AuditInfo auditInfo = new AuditInfo();
                auditInfo.setCreationDate(now);
@@ -1392,17 +1448,6 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
        }
 
        @Override
-       public User updateUser(String username, String name, String mail) throws ObjectNotFoundException {
-               if (username == null)
-                       throw new ObjectNotFoundException("No username specified");
-
-               User user = dao.getUser(username);
-               user.setName(name);
-               user.setEmail(mail);
-               return user;
-       }
-
-       @Override
        public User findUser(String username) {
                if (username == null)
                        return null;
@@ -2579,13 +2624,6 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                return true;
        }
 
-       /**
-        * Reset WebDAV password for given user.
-        *
-        * @param userId
-        * @return the new password
-        * @throws ObjectNotFoundException
-        */
        @Override
        public String resetWebDAVPassword(Long userId) throws ObjectNotFoundException {
                if (userId == null)
@@ -2595,4 +2633,39 @@ public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
                return user.getWebDAVPassword();
        }
 
+       @Override
+       public Invitation findInvite(String code) {
+               if (code == null)
+                       return null;
+               return dao.findInvite(code);
+       }
+
+       @Override
+       public void createLdapUser(String username, String firstname, String lastname, String email, String password) {
+               LDAPConnection lc = new LDAPConnection();
+        LDAPAttributeSet attributeSet = new LDAPAttributeSet();
+        attributeSet.add(new LDAPAttribute("objectClass", getConfiguration().getStringArray("objectClass")));
+        attributeSet.add(new LDAPAttribute("uid", username));
+        attributeSet.add(new LDAPAttribute("cn", new String[]{firstname + " " + lastname}));
+        attributeSet.add(new LDAPAttribute("sn", lastname));
+        attributeSet.add(new LDAPAttribute("givenName", firstname));
+        attributeSet.add(new LDAPAttribute("mail", email));
+        attributeSet.add(new LDAPAttribute("userPassword", password));
+        String dn = "uid=" + username + "," + getConfiguration().getString("baseDn");
+        LDAPEntry newEntry = new LDAPEntry(dn, attributeSet);
+        try {
+               lc.connect(getConfiguration().getString("ldapHost"), LDAPConnection.DEFAULT_PORT);
+               lc.bind(LDAPConnection.LDAP_V3, getConfiguration().getString("bindDn"),
+                               getConfiguration().getString("bindPassword").getBytes("UTF8"));
+               lc.add(newEntry);
+               logger.info("Successfully added LDAP account: " + dn);
+               lc.disconnect();
+        } catch(LDAPException e) {
+               throw new RuntimeException(e);
+        } catch(UnsupportedEncodingException e) {
+               throw new RuntimeException(e);
+        }
+
+       }
+
 }