You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2016/06/23 09:32:20 UTC

[1/5] james-project git commit: JAMES-1759 rename model package into dto

Repository: james-project
Updated Branches:
  refs/heads/master 89ca3b8b4 -> ef4f8d9ef


JAMES-1759 rename model package into dto


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

Branch: refs/heads/master
Commit: ef4f8d9ef1daa487112e30c15a5532b0e9ca88fe
Parents: ff3412f
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Jun 23 11:17:36 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Jun 23 16:31:27 2016 +0700

----------------------------------------------------------------------
 .../james/webadmin/dto/AddUserRequest.java      | 39 ++++++++++++++++++++
 .../james/webadmin/dto/MailboxResponse.java     | 33 +++++++++++++++++
 .../apache/james/webadmin/dto/UserResponse.java | 33 +++++++++++++++++
 .../james/webadmin/model/AddUserRequest.java    | 39 --------------------
 .../james/webadmin/model/MailboxResponse.java   | 33 -----------------
 .../james/webadmin/model/UserResponse.java      | 33 -----------------
 .../james/webadmin/routes/UserRoutes.java       |  2 +-
 .../webadmin/service/UserMailboxesService.java  |  2 +-
 .../james/webadmin/service/UserService.java     |  2 +-
 9 files changed, 108 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/AddUserRequest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/AddUserRequest.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/AddUserRequest.java
new file mode 100644
index 0000000..1d102c2
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/AddUserRequest.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.dto;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
+
+public class AddUserRequest {
+
+    private final char[] password;
+
+    @JsonCreator
+    public AddUserRequest(@JsonProperty("password") char[] password) {
+        Preconditions.checkNotNull(password);
+        this.password = password;
+    }
+
+    public char[] getPassword() {
+        return password;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/MailboxResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/MailboxResponse.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/MailboxResponse.java
new file mode 100644
index 0000000..b552f45
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/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.dto;
+
+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/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/UserResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/UserResponse.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/UserResponse.java
new file mode 100644
index 0000000..5fe1846
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/dto/UserResponse.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.dto;
+
+public class UserResponse {
+
+    private final String username;
+
+    public UserResponse(String username) {
+        this.username = username;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/AddUserRequest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/AddUserRequest.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/AddUserRequest.java
deleted file mode 100644
index b23c7e2..0000000
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/AddUserRequest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************
- * 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;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.Preconditions;
-
-public class AddUserRequest {
-
-    private final char[] password;
-
-    @JsonCreator
-    public AddUserRequest(@JsonProperty("password") char[] password) {
-        Preconditions.checkNotNull(password);
-        this.password = password;
-    }
-
-    public char[] getPassword() {
-        return password;
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/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
deleted file mode 100644
index 593bfd1..0000000
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/MailboxResponse.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************
- * 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/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/UserResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/UserResponse.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/UserResponse.java
deleted file mode 100644
index 9c41c77..0000000
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/model/UserResponse.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************
- * 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 UserResponse {
-
-    private final String username;
-
-    public UserResponse(String username) {
-        this.username = username;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
index 7acda3c..0ead90a 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
@@ -26,7 +26,7 @@ import javax.inject.Inject;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.webadmin.Constants;
 import org.apache.james.webadmin.Routes;
-import org.apache.james.webadmin.model.AddUserRequest;
+import org.apache.james.webadmin.dto.AddUserRequest;
 import org.apache.james.webadmin.service.UserService;
 import org.apache.james.webadmin.utils.JsonExtractException;
 import org.apache.james.webadmin.utils.JsonExtractor;

http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/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
index ef3945e..076675a 100644
--- 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
@@ -35,7 +35,7 @@ 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.dto.MailboxResponse;
 import org.apache.james.webadmin.utils.MailboxHaveChildrenException;
 import org.apache.james.webadmin.validation.MailboxName;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/james-project/blob/ef4f8d9e/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
index bbe4e4e..1eb8ae1 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
@@ -30,7 +30,7 @@ import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
 import org.apache.james.util.streams.ImmutableCollectors;
 import org.apache.james.util.streams.Iterators;
-import org.apache.james.webadmin.model.UserResponse;
+import org.apache.james.webadmin.dto.UserResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 


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


[4/5] james-project git commit: JAMES-1759 Deleting a mailbox should also delete its children

Posted by bt...@apache.org.
JAMES-1759 Deleting a mailbox should also delete its children


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

Branch: refs/heads/master
Commit: ff3412fbe0f28560ae78407a5339bfa0fe2643bf
Parents: a1b8aea
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Jun 23 09:27:48 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Jun 23 16:31:27 2016 +0700

----------------------------------------------------------------------
 server/protocols/webadmin/README.adoc           |  19 +-
 .../webadmin/routes/UserMailboxesRoutes.java    |  22 ++-
 .../webadmin/service/UserMailboxesService.java  |  39 ++--
 .../james/webadmin/validation/MailboxName.java  |  40 +++++
 .../routes/UserMailboxesRoutesTest.java         | 179 +++++++++++++++++--
 5 files changed, 247 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ff3412fb/server/protocols/webadmin/README.adoc
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/README.adoc b/server/protocols/webadmin/README.adoc
index adc3aa5..40942fd 100644
--- a/server/protocols/webadmin/README.adoc
+++ b/server/protocols/webadmin/README.adoc
@@ -132,11 +132,12 @@ curl -XPUT http://ip:port/users/usernameToBeUsed/mailboxes/mailboxNameToBeCreate
 ====
 
 Resource name usernameToBeUsed should be an existing user
-Resource name mailboxNameToBeCreated should not be empty
+Resource name mailboxNameToBeCreated should not be empty, nor contain # & % * characters.
 
 Response codes :
  - 204 : The mailbox now exists on the server
- - 400 : The user name does not exist
+ - 400 : Invalid mailbox name
+ - 404 : 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 :
@@ -146,7 +147,7 @@ Response codes :
  curl -XDELETE http://ip:port/users/usernameToBeUsed/mailboxes/INBOX.work
  ====
 
-=== Deleting a mailbox
+=== Deleting a mailbox and its children
 
 .bash
 ====
@@ -158,8 +159,8 @@ 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.
+ - 400 : Invalid mailbox name
+ - 404 : The user name does not exist
  - 500 : Internal error
 
 === Testing existence of a mailbox
@@ -174,8 +175,8 @@ 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
+ - 400 : Invalid mailbox name
+ - 404 : The user name does not exist, the mailbox does not exist
  - 500 : Internal error
 
 === Listing user mailboxes
@@ -196,7 +197,7 @@ Resource name usernameToBeUsed should be an existing user
 
 Response codes :
  - 200 : The mailboxes list was successfully retrieved
- - 400 : The user name does not exist
+ - 404 : The user name does not exist
  - 500 : Internal error
 
 === Deleting user mailboxes
@@ -210,5 +211,5 @@ 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
+ - 404 : 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/ff3412fb/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
index 127fc1b..717ef2b 100644
--- 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
@@ -26,6 +26,7 @@ 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.apache.james.webadmin.validation.MailboxName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,10 +56,13 @@ public class UserMailboxesRoutes implements Routes {
 
         service.put(SPECIFIC_MAILBOX, (request, response) -> {
             try {
-                userMailboxesService.createMailbox(request.params(USER_NAME), request.params(MAILBOX_NAME));
+                userMailboxesService.createMailbox(request.params(USER_NAME), new MailboxName(request.params(MAILBOX_NAME)));
                 response.status(204);
             } catch (IllegalStateException e) {
                 LOGGER.info("Invalid put on user mailbox", e);
+                response.status(404);
+            } catch (IllegalArgumentException e) {
+                LOGGER.info("Attempt to create an invalid mailbox");
                 response.status(400);
             }
             return Constants.EMPTY_BODY;
@@ -66,14 +70,17 @@ public class UserMailboxesRoutes implements Routes {
 
         service.delete(SPECIFIC_MAILBOX, (request, response) -> {
             try {
-                userMailboxesService.deleteMailbox(request.params(USER_NAME), request.params(MAILBOX_NAME));
+                userMailboxesService.deleteMailbox(request.params(USER_NAME), new MailboxName(request.params(MAILBOX_NAME)));
                 response.status(204);
             } catch (IllegalStateException e) {
                 LOGGER.info("Invalid delete on user mailbox", e);
-                response.status(400);
+                response.status(404);
             } catch (MailboxHaveChildrenException e) {
                 LOGGER.info("Attempt to delete a mailbox with children");
                 response.status(409);
+            } catch (IllegalArgumentException e) {
+                LOGGER.info("Attempt to create an invalid mailbox");
+                response.status(400);
             }
             return Constants.EMPTY_BODY;
         });
@@ -84,20 +91,23 @@ public class UserMailboxesRoutes implements Routes {
                 response.status(204);
             } catch (IllegalStateException e) {
                 LOGGER.info("Invalid delete on user mailboxes", e);
-                response.status(400);
+                response.status(404);
             }
             return Constants.EMPTY_BODY;
         });
 
         service.get(SPECIFIC_MAILBOX, (request, response) -> {
             try {
-                if (userMailboxesService.testMailboxExists(request.params(USER_NAME), request.params(MAILBOX_NAME))) {
+                if (userMailboxesService.testMailboxExists(request.params(USER_NAME), new MailboxName(request.params(MAILBOX_NAME)))) {
                     response.status(204);
                 } else {
                     response.status(404);
                 }
             } catch (IllegalStateException e) {
                 LOGGER.info("Invalid get on user mailbox", e);
+                response.status(404);
+            } catch (IllegalArgumentException e) {
+                LOGGER.info("Attempt to create an invalid mailbox");
                 response.status(400);
             }
             return Constants.EMPTY_BODY;
@@ -109,7 +119,7 @@ public class UserMailboxesRoutes implements Routes {
                 return userMailboxesService.listMailboxes(request.params(USER_NAME));
             } catch (IllegalStateException e) {
                 LOGGER.info("Invalid get on user mailboxes", e);
-                response.status(400);
+                response.status(404);
                 return Constants.EMPTY_BODY;
             }
         }, jsonTransformer);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ff3412fb/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
index 7043d25..ef3945e 100644
--- 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
@@ -37,6 +37,7 @@ 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.apache.james.webadmin.validation.MailboxName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,13 +60,12 @@ public class UserMailboxesService {
         this.usersRepository = usersRepository;
     }
 
-    public void createMailbox(String username, String mailboxName) throws MailboxException, UsersRepositoryException {
+    public void createMailbox(String username, MailboxName 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),
+                convertToMailboxPath(username, mailboxName.asString(), mailboxSession),
                 mailboxSession);
         } catch (MailboxExistsException e) {
             LOGGER.info("Attempt to create mailbox {} for user {} that already exists", mailboxName, username);
@@ -88,40 +88,27 @@ public class UserMailboxesService {
             .collect(ImmutableCollectors.toImmutableList());
     }
 
-    public boolean testMailboxExists(String username, String mailboxName) throws MailboxException, UsersRepositoryException {
+    public boolean testMailboxExists(String username, MailboxName 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),
+            convertToMailboxPath(username, mailboxName.asString(), mailboxSession),
             mailboxSession);
     }
 
-    public void deleteMailbox(String username, String mailboxName) throws MailboxException, UsersRepositoryException, MailboxHaveChildrenException {
+    public void deleteMailbox(String username, MailboxName 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());
-        }
+        MailboxPath mailboxPath = convertToMailboxPath(username, mailboxName.asString(), mailboxSession);
+        listChildren(mailboxPath, mailboxSession)
+            .forEach(Throwing.consumer(path -> deleteMailbox(mailboxSession, path)));
     }
 
-    private boolean haveChildren(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException {
-        return mailboxManager.search(
-            MailboxQuery.builder()
-                .base(mailboxPath)
-                .build(), mailboxSession)
+    private Stream<MailboxPath> listChildren(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxException {
+        return mailboxManager.search(createUserMailboxesQuery(mailboxPath.getUser()), mailboxSession)
             .stream()
-            .findAny()
-            .map(mailboxMetaData -> mailboxMetaData.inferiors() == MailboxMetaData.Children.HAS_CHILDREN)
-            .orElseThrow(() -> new MailboxNotFoundException(mailboxPath));
+            .map(MailboxMetaData::getPath)
+            .filter(path -> path.getHierarchyLevels(mailboxSession.getPathDelimiter()).contains(mailboxPath));
     }
 
     private void deleteMailbox(MailboxSession mailboxSession, MailboxPath mailboxPath) throws MailboxException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/ff3412fb/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/validation/MailboxName.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/validation/MailboxName.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/validation/MailboxName.java
new file mode 100644
index 0000000..fdd079d
--- /dev/null
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/validation/MailboxName.java
@@ -0,0 +1,40 @@
+/****************************************************************
+ * 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.validation;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public class MailboxName {
+
+    public static final CharMatcher INVALID_CHARS_MATCHER = CharMatcher.anyOf("%*&#");
+    private final String mailboxName;
+
+    public MailboxName(String mailboxName) {
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(mailboxName));
+        Preconditions.checkArgument(INVALID_CHARS_MATCHER.matchesNoneOf(mailboxName));
+        this.mailboxName = mailboxName;
+    }
+
+    public String asString() {
+        return mailboxName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ff3412fb/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
index a1782ab..d2ebfb5 100644
--- 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
@@ -109,36 +109,156 @@ public class UserMailboxesRoutesTest {
             when()
                 .get()
             .then()
-                .statusCode(400);
+                .statusCode(404);
         }
 
         @Test
-        public void getShouldReturnUserErrorWithNonExistingUser() throws Exception {
+        public void getShouldReturnNotFoundWithNonExistingUser() throws Exception {
             when(usersRepository.contains(USERNAME)).thenReturn(false);
 
             when()
                 .get(MAILBOX_NAME)
             .then()
-                .statusCode(400);
+                .statusCode(404);
         }
 
         @Test
-        public void putShouldReturnUserErrorWithNonExistingUser() throws Exception {
+        public void putShouldReturnNotFoundWithNonExistingUser() throws Exception {
             when(usersRepository.contains(USERNAME)).thenReturn(false);
 
             when()
                 .put(MAILBOX_NAME)
             .then()
-                .statusCode(400);
+                .statusCode(404);
         }
 
         @Test
-        public void deleteShouldReturnUserErrorWithNonExistingUser() throws Exception {
+        public void deleteShouldReturnNotFoundWithNonExistingUser() throws Exception {
             when(usersRepository.contains(USERNAME)).thenReturn(false);
 
             when()
                 .put(MAILBOX_NAME)
             .then()
+                .statusCode(404);
+        }
+
+        @Test
+        public void getShouldReturnUserErrorWithInvalidWildcardMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .get(MAILBOX_NAME + "*")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void putShouldReturnUserErrorWithInvalidWildcardMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME+ "*")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void deleteShouldReturnUserErrorWithInvalidWildcardMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME + "*")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void getShouldReturnUserErrorWithInvalidPercentMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .get(MAILBOX_NAME + "%")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void putShouldReturnUserErrorWithInvalidPercentMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME+ "%")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void deleteShouldReturnUserErrorWithInvalidPercentMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME + "%")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void getShouldReturnUserErrorWithInvalidSharpMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .get(MAILBOX_NAME + "#")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void putShouldReturnUserErrorWithInvalidSharpMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME+ "#")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void deleteShouldReturnUserErrorWithInvalidSharpMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME + "#")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void getShouldReturnUserErrorWithInvalidAndMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .get(MAILBOX_NAME + "&")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void putShouldReturnUserErrorWithInvalidAndMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME+ "&")
+            .then()
+                .statusCode(400);
+        }
+
+        @Test
+        public void deleteShouldReturnUserErrorWithInvalidAndMailboxName() throws Exception {
+            when(usersRepository.contains(USERNAME)).thenReturn(false);
+
+            when()
+                .put(MAILBOX_NAME + "&")
+            .then()
                 .statusCode(400);
         }
 
@@ -149,7 +269,7 @@ public class UserMailboxesRoutesTest {
             when()
                 .delete()
             .then()
-                .statusCode(400);
+                .statusCode(404);
         }
 
         @Test
@@ -298,7 +418,7 @@ public class UserMailboxesRoutesTest {
         }
 
         @Test
-        public void deleteShouldReturnAConflictWhenMailboxHasChildren() {
+        public void deleteShouldReturnOkWhenMailboxHasChildren() {
             with()
                 .put(MAILBOX_NAME);
 
@@ -308,7 +428,44 @@ public class UserMailboxesRoutesTest {
             when()
                 .delete(MAILBOX_NAME)
             .then()
-                .statusCode(409);
+                .statusCode(204);
+        }
+
+        @Test
+        public void deleteShouldDeleteAMailboxAndItsChildren() {
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .put(MAILBOX_NAME + ".child");
+
+            with()
+                .delete(MAILBOX_NAME);
+
+            when()
+                .get()
+            .then()
+                .statusCode(200)
+                .body(is("[]"));
+        }
+
+        @Test
+        public void deleteShouldNotDeleteUnrelatedMailbox() {
+            String mailboxName = MAILBOX_NAME + "!child";
+            with()
+                .put(MAILBOX_NAME);
+
+            with()
+                .put(mailboxName);
+
+            with()
+                .delete(MAILBOX_NAME);
+
+            when()
+                .get()
+            .then()
+                .statusCode(200)
+                .body(is("[{\"mailboxName\":\"" + mailboxName + "\"}]"));
         }
 
         @Test
@@ -388,7 +545,7 @@ public class UserMailboxesRoutesTest {
 
         @Test
         public void deleteShouldGenerateInternalErrorOnUnknownExceptionOnDelete() throws Exception {
-            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new MailboxPath("#private", USERNAME, "any"), '.')));
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new MailboxPath("#private", USERNAME, MAILBOX_NAME), '.')));
             doThrow(new RuntimeException()).when(mailboxManager).deleteMailbox(any(), any());
 
             when()
@@ -409,7 +566,7 @@ public class UserMailboxesRoutesTest {
 
         @Test
         public void deleteShouldGenerateInternalErrorOnUnknownMailboxExceptionOnDelete() throws Exception {
-            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new MailboxPath("#private", USERNAME, "any"), '.')));
+            when(mailboxManager.search(any(), any())).thenReturn(ImmutableList.of(new SimpleMailboxMetaData(new MailboxPath("#private", USERNAME, MAILBOX_NAME), '.')));
             doThrow(new MailboxException()).when(mailboxManager).deleteMailbox(any(), any());
 
             when()


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


[5/5] james-project git commit: JAMES-1759 CRUD operations on user mailboxes

Posted by bt...@apache.org.
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 <bt...@linagora.com>
Authored: Thu Jun 23 10:14:49 2016 +0700
Committer: Benoit Tellier <bt...@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


[2/5] james-project git commit: JAMES-1759 Integration tests for user mailboxes CRUD operations

Posted by bt...@apache.org.
JAMES-1759 Integration tests for user mailboxes CRUD operations


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

Branch: refs/heads/master
Commit: a1b8aea9b11630f6164dc090aa4a6eb9442915c9
Parents: abdd0a9
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Jun 22 12:01:47 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Jun 23 16:31:27 2016 +0700

----------------------------------------------------------------------
 .../WebAdminServerIntegrationTest.java          | 32 ++++++++++++++++++++
 1 file changed, 32 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a1b8aea9/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
index d720623..f168704 100644
--- a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
+++ b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/WebAdminServerIntegrationTest.java
@@ -33,6 +33,7 @@ import org.apache.james.backends.cassandra.EmbeddedCassandra;
 import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
 import org.apache.james.modules.CassandraJmapServerModule;
 import org.apache.james.webadmin.routes.DomainRoutes;
+import org.apache.james.webadmin.routes.UserMailboxesRoutes;
 import org.apache.james.webadmin.routes.UserRoutes;
 import org.junit.After;
 import org.junit.Before;
@@ -51,6 +52,8 @@ public class WebAdminServerIntegrationTest {
     public static final String USERNAME = "username@" + DOMAIN;
     public static final String SPECIFIC_DOMAIN = DomainRoutes.DOMAINS + SEPARATOR + DOMAIN;
     public static final String SPECIFIC_USER = UserRoutes.USERS + SEPARATOR + USERNAME;
+    public static final String MAILBOX = "mailbox";
+    public static final String SPECIFIC_MAILBOX = SPECIFIC_USER + SEPARATOR + UserMailboxesRoutes.MAILBOXES + SEPARATOR + MAILBOX;
 
     private TemporaryFolder temporaryFolder = new TemporaryFolder();
     private EmbeddedElasticSearch embeddedElasticSearch = new EmbeddedElasticSearch(temporaryFolder);
@@ -146,4 +149,33 @@ public class WebAdminServerIntegrationTest {
             .body(is("[{\"username\":\"username@domain\"}]"));
     }
 
+    @Test
+    public void putMailboxShouldAddAMailbox() throws Exception {
+        guiceJamesServer.serverProbe().addDomain(DOMAIN);
+        guiceJamesServer.serverProbe().addUser(USERNAME, "anyPassword");
+
+        when()
+            .put(SPECIFIC_MAILBOX)
+        .then()
+            .statusCode(204);
+
+        assertThat(guiceJamesServer.serverProbe().listUserMailboxes(USERNAME)).containsExactly(MAILBOX);
+    }
+
+
+
+    @Test
+    public void deleteMailboxShouldRemoveAMailbox() throws Exception {
+        guiceJamesServer.serverProbe().addDomain(DOMAIN);
+        guiceJamesServer.serverProbe().addUser(USERNAME, "anyPassword");
+        guiceJamesServer.serverProbe().createMailbox("#private", USERNAME, MAILBOX);
+
+        when()
+            .delete(SPECIFIC_MAILBOX)
+        .then()
+            .statusCode(204);
+
+        assertThat(guiceJamesServer.serverProbe().listUserMailboxes(USERNAME)).isEmpty();
+    }
+
 }


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


[3/5] james-project git commit: JAMES-1759 Extract emptyBody

Posted by bt...@apache.org.
JAMES-1759 Extract emptyBody


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

Branch: refs/heads/master
Commit: 2e672ff8186927466fb14eceff4ca80d548fc650
Parents: 89ca3b8
Author: Benoit Tellier <bt...@linagora.com>
Authored: Wed Jun 22 11:52:07 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Thu Jun 23 16:31:27 2016 +0700

----------------------------------------------------------------------
 .../main/java/org/apache/james/webadmin/Constants.java    |  1 +
 .../org/apache/james/webadmin/routes/DomainRoutes.java    |  8 ++++----
 .../java/org/apache/james/webadmin/routes/UserRoutes.java | 10 +++++-----
 3 files changed, 10 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2e672ff8/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/Constants.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/Constants.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/Constants.java
index b07ea14..1031a86 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/Constants.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/Constants.java
@@ -22,5 +22,6 @@ package org.apache.james.webadmin;
 public interface Constants {
 
     String SEPARATOR = "/";
+    String EMPTY_BODY = "";
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/2e672ff8/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/DomainRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/DomainRoutes.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/DomainRoutes.java
index bbfa522..2008278 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/DomainRoutes.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/DomainRoutes.java
@@ -25,6 +25,7 @@ import javax.inject.Inject;
 
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.api.DomainListException;
+import org.apache.james.webadmin.Constants;
 import org.apache.james.webadmin.Routes;
 import org.apache.james.webadmin.utils.JsonTransformer;
 import org.slf4j.Logger;
@@ -40,7 +41,6 @@ import spark.Service;
 public class DomainRoutes implements Routes {
 
     private static final String DOMAIN_NAME = ":domainName";
-    private static final String EMPTY_BODY = "";
     private static final Logger LOGGER = LoggerFactory.getLogger(DomainRoutes.class);
 
     public static final String DOMAINS = "/domains";
@@ -78,7 +78,7 @@ public class DomainRoutes implements Routes {
             LOGGER.info("{} did not exists", request.params(DOMAIN_NAME));
         }
         response.status(204);
-        return EMPTY_BODY;
+        return Constants.EMPTY_BODY;
     }
 
     private void removeDomain(String domain) throws DomainListException {
@@ -97,7 +97,7 @@ public class DomainRoutes implements Routes {
             LOGGER.info("Invalid request for domain creation");
             response.status(400);
         }
-        return EMPTY_BODY;
+        return Constants.EMPTY_BODY;
     }
 
     private void addDomain(String domain) throws DomainListException {
@@ -113,6 +113,6 @@ public class DomainRoutes implements Routes {
         } else {
             response.status(204);
         }
-        return EMPTY_BODY;
+        return Constants.EMPTY_BODY;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/2e672ff8/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
index d9f577f..7acda3c 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/routes/UserRoutes.java
@@ -24,6 +24,7 @@ import static org.apache.james.webadmin.Constants.SEPARATOR;
 import javax.inject.Inject;
 
 import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.webadmin.Constants;
 import org.apache.james.webadmin.Routes;
 import org.apache.james.webadmin.model.AddUserRequest;
 import org.apache.james.webadmin.service.UserService;
@@ -40,7 +41,6 @@ import spark.Service;
 public class UserRoutes implements Routes {
 
     private static final String USER_NAME = ":userName";
-    private static final String EMPTY_BODY = "";
     private static final Logger LOGGER = LoggerFactory.getLogger(UserRoutes.class);
 
     public static final String USERS = "/users";
@@ -72,14 +72,14 @@ public class UserRoutes implements Routes {
         try {
             userService.removeUser(username);
             response.status(204);
-            return EMPTY_BODY;
+            return Constants.EMPTY_BODY;
         } catch (UsersRepositoryException e) {
             response.status(204);
             return "The user " + username + " does not exists";
         } catch (IllegalArgumentException e) {
             LOGGER.info("Invalid user path", e);
             response.status(400);
-            return EMPTY_BODY;
+            return Constants.EMPTY_BODY;
         }
     }
 
@@ -91,11 +91,11 @@ public class UserRoutes implements Routes {
         } catch (JsonExtractException e) {
             LOGGER.info("Error while deserializing addUser request", e);
             response.status(400);
-            return EMPTY_BODY;
+            return Constants.EMPTY_BODY;
         } catch (IllegalArgumentException e) {
             LOGGER.info("Invalid user path", e);
             response.status(400);
-            return EMPTY_BODY;
+            return Constants.EMPTY_BODY;
         }
     }
 


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