james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From btell...@apache.org
Subject [5/5] james-project git commit: JAMES-1759 CRUD operations on user mailboxes
Date Thu, 23 Jun 2016 09:32:24 GMT
JAMES-1759 CRUD operations on user mailboxes


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/abdd0a98
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/abdd0a98
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/abdd0a98

Branch: refs/heads/master
Commit: abdd0a98db423a6149ee4d302d27e05c7ee5e81b
Parents: 2e672ff
Author: Benoit Tellier <btellier@linagora.com>
Authored: Thu Jun 23 10:14:49 2016 +0700
Committer: Benoit Tellier <btellier@linagora.com>
Committed: Thu Jun 23 16:31:27 2016 +0700

----------------------------------------------------------------------
 .../modules/server/WebAdminServerModule.java    |   2 +
 server/protocols/webadmin/README.adoc           |  93 ++-
 server/protocols/webadmin/pom.xml               |  13 +
 .../james/webadmin/model/MailboxResponse.java   |  33 ++
 .../webadmin/routes/UserMailboxesRoutes.java    | 118 ++++
 .../webadmin/service/UserMailboxesService.java  | 156 +++++
 .../utils/MailboxHaveChildrenException.java     |  27 +
 .../routes/UserMailboxesRoutesTest.java         | 587 +++++++++++++++++++
 8 files changed, 1028 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
index 4e88950..cf78598 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
@@ -36,6 +36,7 @@ import org.apache.james.webadmin.Port;
 import org.apache.james.webadmin.Routes;
 import org.apache.james.webadmin.WebAdminServer;
 import org.apache.james.webadmin.routes.DomainRoutes;
+import org.apache.james.webadmin.routes.UserMailboxesRoutes;
 import org.apache.james.webadmin.routes.UserRoutes;
 import org.apache.james.webadmin.utils.JsonTransformer;
 
@@ -59,6 +60,7 @@ public class WebAdminServerModule extends AbstractModule {
         Multibinder<Routes> routesMultibinder = Multibinder.newSetBinder(binder(),
Routes.class);
         routesMultibinder.addBinding().to(DomainRoutes.class);
         routesMultibinder.addBinding().to(UserRoutes.class);
+        routesMultibinder.addBinding().to(UserMailboxesRoutes.class);
 
         Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(WebAdminServerModuleConfigurationPerformer.class);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/README.adoc
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/README.adoc b/server/protocols/webadmin/README.adoc
index 7f09778..adc3aa5 100644
--- a/server/protocols/webadmin/README.adoc
+++ b/server/protocols/webadmin/README.adoc
@@ -1,6 +1,6 @@
 = Web administration for JAMES
 
-The web administration supports for now the CRUD operations on the domains and the users,
as described in the following sections.
+The web administration supports for now the CRUD operations on the domains, the users and
the users mailboxes, as described in the following sections.
 
 **WARNING** : This API do not allow authentication for now. It means that an administrator
should ensure an attacker can not use this API.
 
@@ -121,3 +121,94 @@ The answer looks like :
 Response codes :
  - 200 : The user name list was successfully retrieved
  - 500 : Internal error while retrieving the users
+
+== Administrating user mailboxes
+
+=== Creating a mailbox
+
+.bash
+====
+curl -XPUT http://ip:port/users/usernameToBeUsed/mailboxes/mailboxNameToBeCreated
+====
+
+Resource name usernameToBeUsed should be an existing user
+Resource name mailboxNameToBeCreated should not be empty
+
+Response codes :
+ - 204 : The mailbox now exists on the server
+ - 400 : The user name does not exist
+ - 500 : Internal error
+
+ To create nested mailboxes, for instance a work mailbox inside the INBOX mailbox, people
should use the . separator. The sample query is :
+
+ .bash
+ ====
+ curl -XDELETE http://ip:port/users/usernameToBeUsed/mailboxes/INBOX.work
+ ====
+
+=== Deleting a mailbox
+
+.bash
+====
+curl -XDELETE http://ip:port/users/usernameToBeUsed/mailboxes/mailboxNameToBeCreated
+====
+
+Resource name usernameToBeUsed should be an existing user
+Resource name mailboxNameToBeCreated should not be empty
+
+Response codes :
+ - 204 : The mailbox now does not exist on the server
+ - 400 : The user name does not exist
+ - 409 : The mailbox can not be deleted due to its children mailboxes. Delete children mailboxes
first.
+ - 500 : Internal error
+
+=== Testing existence of a mailbox
+
+.bash
+====
+curl -XGET http://ip:port/users/usernameToBeUsed/mailboxes/mailboxNameToBeCreated
+====
+
+Resource name usernameToBeUsed should be an existing user
+Resource name mailboxNameToBeCreated should not be empty
+
+Response codes :
+ - 204 : The mailbox exists
+ - 400 : The user name does not exist
+ - 404 : The mailbox does not exist
+ - 500 : Internal error
+
+=== Listing user mailboxes
+
+.bash
+====
+curl -XGET http://ip:port/users/usernameToBeUsed/mailboxes
+====
+
+The answer looks like :
+
+.json
+====
+[{"mailboxName":"INBOX"},{"mailboxName":"outbox"}]
+====
+
+Resource name usernameToBeUsed should be an existing user
+
+Response codes :
+ - 200 : The mailboxes list was successfully retrieved
+ - 400 : The user name does not exist
+ - 500 : Internal error
+
+=== Deleting user mailboxes
+
+.bash
+====
+curl -XDELETE http://ip:port/users/usernameToBeUsed/mailboxes
+====
+
+Resource name usernameToBeUsed should be an existing user
+
+Response codes :
+ - 204 : The user do not have mailboxes anymore
+ - 400 : The user name does not exist
+ - 500 : Internal error
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/pom.xml b/server/protocols/webadmin/pom.xml
index a23ee8e..725d192 100644
--- a/server/protocols/webadmin/pom.xml
+++ b/server/protocols/webadmin/pom.xml
@@ -150,6 +150,15 @@
             <dependencies>
                 <dependency>
                     <groupId>org.apache.james</groupId>
+                    <artifactId>apache-james-mailbox-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.james</groupId>
+                    <artifactId>apache-james-mailbox-memory</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.james</groupId>
                     <artifactId>james-server-util-java8</artifactId>
                 </dependency>
                 <dependency>
@@ -170,6 +179,10 @@
                     <artifactId>jackson-databind</artifactId>
                 </dependency>
                 <dependency>
+                    <groupId>com.github.fge</groupId>
+                    <artifactId>throwing-lambdas</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>com.google.guava</groupId>
                     <artifactId>guava</artifactId>
                 </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/MailboxResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/MailboxResponse.java
b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/MailboxResponse.java
new file mode 100644
index 0000000..593bfd1
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/MailboxResponse.java
@@ -0,0 +1,33 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.model;
+
+public class MailboxResponse {
+
+    private final String mailboxName;
+
+    public MailboxResponse(String mailboxName) {
+        this.mailboxName = mailboxName;
+    }
+
+    public String getMailboxName() {
+        return mailboxName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java
b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java
new file mode 100644
index 0000000..127fc1b
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserMailboxesRoutes.java
@@ -0,0 +1,118 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.routes;
+
+import javax.inject.Inject;
+
+import org.apache.james.webadmin.Constants;
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.service.UserMailboxesService;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.apache.james.webadmin.utils.MailboxHaveChildrenException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import spark.Service;
+
+public class UserMailboxesRoutes implements Routes {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserMailboxesRoutes.class);
+
+    public static final String MAILBOX_NAME = ":mailboxName";
+    public static final String MAILBOXES = "mailboxes";
+    private static final String USER_NAME = ":userName";
+    public static final String USER_MAILBOXES_BASE = UserRoutes.USERS + Constants.SEPARATOR
+ USER_NAME + Constants.SEPARATOR + MAILBOXES;
+    public static final String SPECIFIC_MAILBOX = USER_MAILBOXES_BASE + Constants.SEPARATOR
+ MAILBOX_NAME;
+
+    private final UserMailboxesService userMailboxesService;
+    private final JsonTransformer jsonTransformer;
+
+    @Inject
+    public UserMailboxesRoutes(UserMailboxesService userMailboxesService, JsonTransformer
jsonTransformer) {
+        this.userMailboxesService = userMailboxesService;
+        this.jsonTransformer = jsonTransformer;
+    }
+
+    @Override
+    public void define(Service service) {
+
+        service.put(SPECIFIC_MAILBOX, (request, response) -> {
+            try {
+                userMailboxesService.createMailbox(request.params(USER_NAME), request.params(MAILBOX_NAME));
+                response.status(204);
+            } catch (IllegalStateException e) {
+                LOGGER.info("Invalid put on user mailbox", e);
+                response.status(400);
+            }
+            return Constants.EMPTY_BODY;
+        });
+
+        service.delete(SPECIFIC_MAILBOX, (request, response) -> {
+            try {
+                userMailboxesService.deleteMailbox(request.params(USER_NAME), request.params(MAILBOX_NAME));
+                response.status(204);
+            } catch (IllegalStateException e) {
+                LOGGER.info("Invalid delete on user mailbox", e);
+                response.status(400);
+            } catch (MailboxHaveChildrenException e) {
+                LOGGER.info("Attempt to delete a mailbox with children");
+                response.status(409);
+            }
+            return Constants.EMPTY_BODY;
+        });
+
+        service.delete(USER_MAILBOXES_BASE, (request, response) -> {
+            try {
+                userMailboxesService.deleteMailboxes(request.params(USER_NAME));
+                response.status(204);
+            } catch (IllegalStateException e) {
+                LOGGER.info("Invalid delete on user mailboxes", e);
+                response.status(400);
+            }
+            return Constants.EMPTY_BODY;
+        });
+
+        service.get(SPECIFIC_MAILBOX, (request, response) -> {
+            try {
+                if (userMailboxesService.testMailboxExists(request.params(USER_NAME), request.params(MAILBOX_NAME)))
{
+                    response.status(204);
+                } else {
+                    response.status(404);
+                }
+            } catch (IllegalStateException e) {
+                LOGGER.info("Invalid get on user mailbox", e);
+                response.status(400);
+            }
+            return Constants.EMPTY_BODY;
+        });
+
+        service.get(USER_MAILBOXES_BASE, (request, response) -> {
+            response.status(200);
+            try {
+                return userMailboxesService.listMailboxes(request.params(USER_NAME));
+            } catch (IllegalStateException e) {
+                LOGGER.info("Invalid get on user mailboxes", e);
+                response.status(400);
+                return Constants.EMPTY_BODY;
+            }
+        }, jsonTransformer);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
new file mode 100644
index 0000000..7043d25
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
@@ -0,0 +1,156 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.service;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxExistsException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxMetaData;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MailboxQuery;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.util.streams.ImmutableCollectors;
+import org.apache.james.webadmin.model.MailboxResponse;
+import org.apache.james.webadmin.utils.MailboxHaveChildrenException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+
+public class UserMailboxesService {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserMailboxesService.class);
+    private static final String USER_NAME = "webAdmin";
+
+    private final MailboxManager mailboxManager;
+    private final UsersRepository usersRepository;
+
+    @Inject
+    public UserMailboxesService(MailboxManager mailboxManager, UsersRepository usersRepository)
{
+        this.mailboxManager = mailboxManager;
+        this.usersRepository = usersRepository;
+    }
+
+    public void createMailbox(String username, String mailboxName) throws MailboxException,
UsersRepositoryException {
+        usernamePreconditions(username);
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(mailboxName));
+        MailboxSession mailboxSession = mailboxManager.createSystemSession(USER_NAME, LOGGER);
+        try {
+            mailboxManager.createMailbox(
+                convertToMailboxPath(username, mailboxName, mailboxSession),
+                mailboxSession);
+        } catch (MailboxExistsException e) {
+            LOGGER.info("Attempt to create mailbox {} for user {} that already exists", mailboxName,
username);
+        }
+    }
+
+    public void deleteMailboxes(String username) throws MailboxException, UsersRepositoryException
{
+        usernamePreconditions(username);
+        MailboxSession mailboxSession = mailboxManager.createSystemSession(USER_NAME, LOGGER);
+        listUserMailboxes(username, mailboxSession)
+            .map(MailboxMetaData::getPath)
+            .forEach(Throwing.consumer(mailboxPath -> deleteMailbox(mailboxSession, mailboxPath)));
+    }
+
+    public List<MailboxResponse> listMailboxes(String username) throws MailboxException,
UsersRepositoryException {
+        usernamePreconditions(username);
+        MailboxSession mailboxSession = mailboxManager.createSystemSession(USER_NAME, LOGGER);
+        return listUserMailboxes(username, mailboxSession)
+            .map(mailboxMetaData -> new MailboxResponse(mailboxMetaData.getPath().getName()))
+            .collect(ImmutableCollectors.toImmutableList());
+    }
+
+    public boolean testMailboxExists(String username, String mailboxName) throws MailboxException,
UsersRepositoryException {
+        usernamePreconditions(username);
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(mailboxName));
+        MailboxSession mailboxSession = mailboxManager.createSystemSession(USER_NAME, LOGGER);
+        return mailboxManager.mailboxExists(
+            convertToMailboxPath(username, mailboxName, mailboxSession),
+            mailboxSession);
+    }
+
+    public void deleteMailbox(String username, String mailboxName) throws MailboxException,
UsersRepositoryException, MailboxHaveChildrenException {
+        usernamePreconditions(username);
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(mailboxName));
+        MailboxSession mailboxSession = mailboxManager.createSystemSession(USER_NAME, LOGGER);
+        MailboxPath mailboxPath = convertToMailboxPath(username, mailboxName, mailboxSession);
+        try {
+            if (!haveChildren(mailboxPath, mailboxSession)) {
+                deleteMailbox(mailboxSession, mailboxPath);
+            } else {
+                throw new MailboxHaveChildrenException(mailboxName);
+            }
+        } catch (MailboxNotFoundException e) {
+            LOGGER.info("Attempt to delete mailbox {} for user {} that does not exists",
mailboxPath.getName(), mailboxPath.getUser());
+        }
+    }
+
+    private boolean haveChildren(MailboxPath mailboxPath, MailboxSession mailboxSession)
throws MailboxException {
+        return mailboxManager.search(
+            MailboxQuery.builder()
+                .base(mailboxPath)
+                .build(), mailboxSession)
+            .stream()
+            .findAny()
+            .map(mailboxMetaData -> mailboxMetaData.inferiors() == MailboxMetaData.Children.HAS_CHILDREN)
+            .orElseThrow(() -> new MailboxNotFoundException(mailboxPath));
+    }
+
+    private void deleteMailbox(MailboxSession mailboxSession, MailboxPath mailboxPath) throws
MailboxException {
+        try {
+            mailboxManager.deleteMailbox(mailboxPath, mailboxSession);
+        } catch (MailboxNotFoundException e) {
+            LOGGER.info("Attempt to delete mailbox {} for user {} that does not exists",
mailboxPath.getName(), mailboxPath.getUser());
+        }
+    }
+
+    private void usernamePreconditions(String username) throws UsersRepositoryException {
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(username));
+        Preconditions.checkState(usersRepository.contains(username));
+    }
+
+    private MailboxPath convertToMailboxPath(String username, String mailboxName, MailboxSession
mailboxSession) {
+        return new MailboxPath(mailboxSession.getPersonalSpace(), username, mailboxName);
+    }
+
+    private Stream<MailboxMetaData> listUserMailboxes(String username, MailboxSession
mailboxSession) throws MailboxException {
+        return mailboxManager.search(createUserMailboxesQuery(username), mailboxSession)
+            .stream();
+    }
+
+    private MailboxQuery createUserMailboxesQuery(String username) {
+        return MailboxQuery.builder()
+            .username(username)
+            .privateUserMailboxes()
+            .build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/utils/MailboxHaveChildrenException.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/utils/MailboxHaveChildrenException.java
b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/utils/MailboxHaveChildrenException.java
new file mode 100644
index 0000000..ae8213e
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/utils/MailboxHaveChildrenException.java
@@ -0,0 +1,27 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.utils;
+
+public class MailboxHaveChildrenException extends Exception {
+
+    public MailboxHaveChildrenException(String mailboxName) {
+        super(mailboxName + "have children");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/abdd0a98/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
b/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
new file mode 100644
index 0000000..a1782ab
--- /dev/null
+++ b/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/routes/UserMailboxesRoutesTest.java
@@ -0,0 +1,587 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.webadmin.routes;
+
+import static com.jayway.restassured.RestAssured.when;
+import static com.jayway.restassured.RestAssured.with;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.apache.james.webadmin.Constants.SEPARATOR;
+import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION;
+import static org.hamcrest.CoreMatchers.is;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxExistsException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.JVMMailboxPathLocker;
+import org.apache.james.mailbox.store.SimpleMailboxMetaData;
+import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.service.UserMailboxesService;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.parsing.Parser;
+
+import de.bechte.junit.runners.context.HierarchicalContextRunner;
+
+@RunWith(HierarchicalContextRunner.class)
+public class UserMailboxesRoutesTest {
+
+    public static final String USERNAME = "username";
+    public static final String MAILBOX_NAME = "myMailboxName";
+    private WebAdminServer webAdminServer;
+    private UsersRepository usersRepository;
+
+    private void createServer(MailboxManager mailboxManager) throws Exception {
+        usersRepository = mock(UsersRepository.class);
+        when(usersRepository.contains(USERNAME)).thenReturn(true);
+
+        webAdminServer = new WebAdminServer(new UserMailboxesRoutes(new UserMailboxesService(mailboxManager,
usersRepository), new JsonTransformer()));
+        webAdminServer.configure(NO_CONFIGURATION);
+        webAdminServer.await();
+
+        RestAssured.port = webAdminServer.getPort().toInt();
+        RestAssured.config = newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+        RestAssured.defaultParser = Parser.JSON;
+        RestAssured.basePath = UserRoutes.USERS + SEPARATOR + USERNAME + SEPARATOR + UserMailboxesRoutes.MAILBOXES;
+    }
+
+    @After
+    public void tearDown() {
+        webAdminServer.destroy();
+    }
+
+    public class NormalBehaviour {
+
+        @Before
+        public void setUp() throws Exception {
+            InMemoryMailboxManager mailboxManager = new InMemoryMailboxManager(new InMemoryMailboxSessionMapperFactory(),
+                (userid, passwd) -> true,
+                new JVMMailboxPathLocker(),
+                new UnionMailboxACLResolver(),
+                new SimpleGroupMembershipResolver(),
+                new MessageParser());
+            mailboxManager.init();
+
+            createServer(mailboxManager);
+        }
+
+        @Test
+        public void getMailboxesShouldUserErrorFoundWithNonExistingUser() throws Exception
{
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .get()
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void getShouldReturnUserErrorWithNonExistingUser() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void putShouldReturnUserErrorWithNonExistingUser() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void deleteShouldReturnUserErrorWithNonExistingUser() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void deleteMailboxesShouldReturnUserErrorWithNonExistingUser() throws Exception
{
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .delete()
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void getMailboxesShouldReturnEmptyListByDefault() {
+            when()
+                .get()
+            .then()
+                .statusCode(200)
+                .body(is("[]"));
+        }
+
+        @Test
+        public void putShouldReturnNotFoundWhenNoMailboxName() {
+            when()
+                .put()
+            .then()
+                .statusCode(404);
+        }
+
+        @Test
+        public void putShouldReturnNotFoundWhenJustSeparator() {
+            when()
+                .put(SEPARATOR)
+            .then()
+                .statusCode(404);
+        }
+
+        @Test
+        public void putShouldReturnOk() {
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void putShouldReturnOkWhenIssuedTwoTimes() {
+            with()
+                .put(MAILBOX_NAME);
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void putShouldAddAMailbox() {
+            with()
+                .put(MAILBOX_NAME);
+
+            when()
+                .get()
+            .then()
+                .statusCode(200)
+                .body(is("[{\"mailboxName\":\"myMailboxName\"}]"));
+        }
+
+        @Test
+        public void getShouldReturnNotFoundWhenMailboxDoesNotExist() {
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(404);
+        }
+
+        @Test
+        public void getShouldReturnOkWhenMailboxExists() {
+            with()
+                .put(MAILBOX_NAME);
+
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldReturnOkWhenMailboxDoesNotExist() {
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldReturnOkWhenMailboxExists() {
+            with()
+                .put(MAILBOX_NAME);
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldRemoveMailbox() {
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .delete(MAILBOX_NAME);
+
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(404);
+        }
+
+        @Test
+        public void deleteMailboxesShouldReturnOkWhenNoMailboxes() {
+            when()
+                .delete()
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteMailboxesShouldReturnOkWhenMailboxes() {
+            with()
+                .put(MAILBOX_NAME);
+
+            when()
+                .delete()
+                .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteMailboxesShouldRemoveAllUserMailboxes() {
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .put("otherMailbox");
+
+            with()
+                .delete();
+
+            when()
+                .get()
+            .then()
+                .statusCode(200)
+                .body(is("[]"));
+        }
+
+        @Test
+        public void deleteShouldReturnAConflictWhenMailboxHasChildren() {
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .put(MAILBOX_NAME + ".child");
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(409);
+        }
+
+        @Test
+        public void deleteShouldReturnOkWhenDeletingChildMailboxes() {
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .put(MAILBOX_NAME + ".child");
+
+            when()
+                .delete(MAILBOX_NAME + ".child")
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldBeAbleToRemoveChildMailboxes() {
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .put(MAILBOX_NAME + ".child");
+
+            with()
+                .delete(MAILBOX_NAME + ".child");
+
+            when()
+                .get()
+            .then()
+                .statusCode(200)
+                .body(is("[{\"mailboxName\":\"myMailboxName\"}]"));
+        }
+    }
+
+    public class ExceptionHandling {
+
+        private MailboxManager mailboxManager;
+
+        @Before
+        public void setUp() throws Exception {
+            mailboxManager = mock(MailboxManager.class);
+            when(mailboxManager.createSystemSession(any(), any())).thenReturn(mock(MailboxSession.class));
+
+            createServer(mailboxManager);
+        }
+
+        @Test
+        public void putShouldGenerateInternalErrorOnUnknownException() throws Exception {
+            doThrow(new RuntimeException()).when(mailboxManager).createMailbox(any(), any());
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void putShouldGenerateInternalErrorOnUnknownMailboxException() throws Exception
{
+            doThrow(new MailboxException()).when(mailboxManager).createMailbox(any(), any());
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void putShouldReturnOkOnMailboxExists() throws Exception {
+            doThrow(new MailboxExistsException(MAILBOX_NAME)).when(mailboxManager).createMailbox(any(),
any());
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnUnknownExceptionOnDelete() throws
Exception {
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new
MailboxPath("#private", USERNAME, "any"), '.')));
+            doThrow(new RuntimeException()).when(mailboxManager).deleteMailbox(any(), any());
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnUnknownExceptionOnSearch() throws
Exception {
+            when(mailboxManager.search(any(), any())).thenThrow(new RuntimeException());
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnUnknownMailboxExceptionOnDelete()
throws Exception {
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new
MailboxPath("#private", USERNAME, "any"), '.')));
+            doThrow(new MailboxException()).when(mailboxManager).deleteMailbox(any(), any());
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnUnknownMailboxExceptionOnSearch()
throws Exception {
+            when(mailboxManager.search(any(), any())).thenThrow(new MailboxException());
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldReturnOkOnMailboxDoesNotExists() throws Exception {
+            doThrow(new MailboxNotFoundException(MAILBOX_NAME)).when(mailboxManager).deleteMailbox(any(),
any());
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnUnknownExceptionWhenListingMailboxes()
throws Exception {
+            doThrow(new RuntimeException()).when(mailboxManager).search(any(), any());
+
+            when()
+                .delete()
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnMailboxExceptionWhenListingMailboxes()
throws Exception {
+            doThrow(new MailboxException()).when(mailboxManager).search(any(), any());
+
+            when()
+                .delete()
+                .then()
+                .statusCode(500);
+        }
+
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnUnknownExceptionWhenRemovingMailboxes()
throws Exception {
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new
MailboxPath("#private", USERNAME, "any"), '.')));
+            doThrow(new RuntimeException()).when(mailboxManager).deleteMailbox(any(), any());
+
+            when()
+                .delete()
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldReturnOkOnMailboxNotFoundExceptionWhenRemovingMailboxes()
throws Exception {
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new
MailboxPath("#private", USERNAME, "any"), '.')));
+            doThrow(new MailboxNotFoundException("any")).when(mailboxManager).deleteMailbox(any(),
any());
+
+            when()
+                .delete()
+            .then()
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldReturnInternalErrorOnMailboxExceptionWhenRemovingMailboxes()
throws Exception {
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new
MailboxPath("#private", USERNAME, "any"), '.')));
+            doThrow(new MailboxException()).when(mailboxManager).deleteMailbox(any(), any());
+
+            when()
+                .delete()
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void getShouldGenerateInternalErrorOnUnknownException() throws Exception {
+            doThrow(new RuntimeException()).when(mailboxManager).mailboxExists(any(), any());
+
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void getShouldGenerateInternalErrorOnUnknownMailboxException() throws Exception
{
+            doThrow(new MailboxException()).when(mailboxManager).mailboxExists(any(), any());
+
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void getMailboxesShouldGenerateInternalErrorOnUnknownException() throws Exception
{
+            doThrow(new RuntimeException()).when(mailboxManager).search(any(), any());
+
+            when()
+                .get()
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void getMailboxesShouldGenerateInternalErrorOnUnknownMailboxException() throws
Exception {
+            doThrow(new MailboxException()).when(mailboxManager).search(any(), any());
+
+            when()
+                .get()
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void getMailboxesShouldGenerateInternalErrorOnRepositoryException() throws
Exception {
+            doThrow(new RuntimeException()).when(usersRepository).contains(USERNAME);
+
+            when()
+                .get()
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void getShouldGenerateInternalErrorOnRepositoryException() throws Exception
{
+            doThrow(new RuntimeException()).when(usersRepository).contains(USERNAME);
+
+            when()
+                .get(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void putShouldGenerateInternalErrorOnRepositoryException() throws Exception
{
+            doThrow(new RuntimeException()).when(usersRepository).contains(USERNAME);
+
+            when()
+                .put(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteShouldGenerateInternalErrorOnRepositoryException() throws Exception
{
+            doThrow(new RuntimeException()).when(usersRepository).contains(USERNAME);
+
+            when()
+                .delete(MAILBOX_NAME)
+            .then()
+                .statusCode(500);
+        }
+
+        @Test
+        public void deleteMailboxesShouldGenerateInternalErrorOnRepositoryException() throws
Exception {
+            doThrow(new RuntimeException()).when(usersRepository).contains(USERNAME);
+
+            when()
+                .delete()
+                .then()
+                .statusCode(500);
+        }
+
+    }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message