Author: norman
Date: Sun Jan 29 13:52:44 2012
New Revision: 1237290

URL: http://svn.apache.org/viewvc?rev=1237290&view=rev
Log:
Merge support for ACL in. See IMAP-351

Added:
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/GetACLCommandParser.java
   (with props)
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/ACLResponseEncoder.java
   (with props)
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/request/GetACLRequest.java
   (with props)
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/response/ACLResponse.java
   (with props)
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
   (with props)
    
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java
   (with props)
    
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/StatusResponseTypeMatcher.java
   (with props)
Modified:
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
    
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
    
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java

Modified: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java?rev=1237290&r1=1237289&r2=1237290&view=diff
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
 (original)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
 Sun Jan 29 13:52:44 2012
@@ -103,6 +103,8 @@ public interface ImapConstants {
     
     public static final String SUPPORTS_QRESYNC = "QRESYNC";
 
+    public static final String SUPPORTS_ACL = "ACL";
+    
     public static final String INBOX_NAME = "INBOX";
 
     public static final String MIME_TYPE_TEXT = "TEXT";
@@ -212,6 +214,16 @@ public interface ImapConstants {
     public static final String APPEND_COMMAND_NAME = "APPEND";
     
     public static final String ENABLE_COMMAND_NAME = "ENABLE";
+    
+    public static final String GETACL_COMMAND_NAME = "GETACL";
+
+    public static final String SETACL_COMMAND_NAME = "SETACL";
+    
+    public static final String DELETEACL_COMMAND_NAME = "DELETEACL";
+    
+    public static final String LISTRIGHTS_COMMAND_NAME = "LISTRIGHTS";
+    
+    public static final String MYRIGHTS_COMMAND_NAME = "MYRIGHTS";
 
     public static final String LIST_RESPONSE_NAME = "LIST";
 
@@ -221,6 +233,8 @@ public interface ImapConstants {
 
     public static final String SEARCH_RESPONSE_NAME = "SEARCH";
 
+    public static final String ACL_RESPONSE_NAME = "ACL";
+
     public static final String NAME_ATTRIBUTE_NOINFERIORS = "\\Noinferiors";
 
     public static final String NAME_ATTRIBUTE_NOSELECT = "\\Noselect";

Added: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/GetACLCommandParser.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/GetACLCommandParser.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/GetACLCommandParser.java
 (added)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/GetACLCommandParser.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,48 @@
+/****************************************************************
+ * 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.imap.decode.parser;
+
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.decode.ImapRequestLineReader;
+import org.apache.james.imap.decode.base.AbstractImapCommandParser;
+import org.apache.james.imap.message.request.GetACLRequest;
+import org.apache.james.protocols.imap.DecodingException;
+
+/**
+ * GETACL Parser
+ * 
+ */
+public class GetACLCommandParser extends AbstractImapCommandParser {
+
+    public GetACLCommandParser() {
+        
super(ImapCommand.authenticatedStateCommand(ImapConstants.GETACL_COMMAND_NAME));
+    }
+
+    @Override
+    protected ImapMessage decode(ImapCommand command, ImapRequestLineReader 
request, String tag, ImapSession session) throws DecodingException {
+        final String mailboxName = request.mailbox();
+        request.eol();
+        return new GetACLRequest(tag, command, mailboxName);
+    }
+
+}

Propchange: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/GetACLCommandParser.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java?rev=1237290&r1=1237289&r2=1237290&view=diff
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
 (original)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java
 Sun Jan 29 13:52:44 2012
@@ -72,8 +72,8 @@ public class ImapParserFactory implement
         // RFC2342 NAMESPACE
         _imapCommands.put(ImapConstants.NAMESPACE_COMMAND_NAME, 
NamespaceCommandParser.class);
 
-        // RFC2086 GETACL, SETACL, DELETEACL, LISTRIGHTS, MYRIGHTS
-        // _imapCommands.put( "GETACL", GetAclCommand.class );
+        // RFC4314 GETACL, SETACL, DELETEACL, LISTRIGHTS, MYRIGHTS
+        _imapCommands.put(ImapConstants.GETACL_COMMAND_NAME, 
GetACLCommandParser.class );
         // _imapCommands.put( "SETACL", SetAclCommand.class );
         // _imapCommands.put( "DELETEACL", DeleteAclCommand.class );
         // _imapCommands.put( "LISTRIGHTS", ListRightsCommand.class );

Added: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/ACLResponseEncoder.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/ACLResponseEncoder.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/ACLResponseEncoder.java
 (added)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/ACLResponseEncoder.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,83 @@
+/****************************************************************
+ * 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.imap.encode;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
+import org.apache.james.imap.message.response.ACLResponse;
+import org.apache.james.mailbox.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.MailboxACL.MailboxACLRights;
+
+/**
+ * ACL Response Encoder.
+ * 
+ */
+public class ACLResponseEncoder extends AbstractChainedImapEncoder {
+
+    public ACLResponseEncoder(ImapEncoder next) {
+        super(next);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.james.imap.encode.base.AbstractChainedImapEncoder#doEncode
+     * (org.apache.james.imap.api.ImapMessage,
+     * org.apache.james.imap.encode.ImapResponseComposer,
+     * org.apache.james.imap.api.process.ImapSession)
+     */
+    protected void doEncode(ImapMessage acceptableMessage, 
ImapResponseComposer composer, ImapSession session) throws IOException {
+        final ACLResponse aclResponse = (ACLResponse) acceptableMessage;
+        final Map<MailboxACLEntryKey, MailboxACLRights> entries = 
aclResponse.getAcl().getEntries();
+        composer.untagged();
+        composer.commandName(ImapConstants.ACL_RESPONSE_NAME);
+        
+        String mailboxName = aclResponse.getMailboxName();
+        composer.quote(mailboxName == null ? "" : mailboxName);
+        
+        if (entries != null) {
+            for (Entry<MailboxACLEntryKey, MailboxACLRights> entry : 
entries.entrySet()) {
+                String identifier = entry.getKey().serialize();
+                composer.quote(identifier);
+                String rights = entry.getValue().serialize();
+                composer.quote(rights == null ? "" : rights);
+            }
+        }
+        composer.end();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * 
org.apache.james.imap.encode.base.AbstractChainedImapEncoder#isAcceptable
+     * (org.apache.james.imap.api.ImapMessage)
+     */
+    public boolean isAcceptable(ImapMessage message) {
+        return message instanceof ACLResponse;
+    }
+}

Propchange: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/ACLResponseEncoder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java?rev=1237290&r1=1237289&r2=1237290&view=diff
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
 (original)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
 Sun Jan 29 13:52:44 2012
@@ -20,6 +20,7 @@
 package org.apache.james.imap.encode.main;
 
 import org.apache.james.imap.api.display.Localizer;
+import org.apache.james.imap.encode.ACLResponseEncoder;
 import org.apache.james.imap.encode.AuthenticateResponseEncoder;
 import org.apache.james.imap.encode.CapabilityResponseEncoder;
 import org.apache.james.imap.encode.ContinuationResponseEncoder;
@@ -59,7 +60,9 @@ public class DefaultImapEncoderFactory i
      */
     public static final ImapEncoder createDefaultEncoder(final Localizer 
localizer, final boolean neverAddBodyStructureExtensions) {
         final EndImapEncoder endImapEncoder = new EndImapEncoder();
-        final NamespaceResponseEncoder namespaceEncoder = new 
NamespaceResponseEncoder(endImapEncoder);
+        
+        final ACLResponseEncoder aclResponseEncoder = new 
ACLResponseEncoder(endImapEncoder); 
+        final NamespaceResponseEncoder namespaceEncoder = new 
NamespaceResponseEncoder(aclResponseEncoder);
         final StatusResponseEncoder statusResponseEncoder = new 
StatusResponseEncoder(namespaceEncoder, localizer);
         final RecentResponseEncoder recentResponseEncoder = new 
RecentResponseEncoder(statusResponseEncoder);
         final FetchResponseEncoder fetchResponseEncoder = new 
FetchResponseEncoder(recentResponseEncoder, neverAddBodyStructureExtensions);

Added: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/request/GetACLRequest.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/request/GetACLRequest.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/request/GetACLRequest.java
 (added)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/request/GetACLRequest.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,41 @@
+/****************************************************************
+ * 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.imap.message.request;
+
+import org.apache.james.imap.api.ImapCommand;
+
+/**
+ * GETACL Request.
+ * 
+ * @author Peter Palaga
+ */
+public class GetACLRequest extends AbstractImapRequest {
+    private final String mailboxName;
+
+    public GetACLRequest(String tag, ImapCommand command, String mailboxName) {
+        super(tag, command);
+        this.mailboxName = mailboxName;
+    }
+
+    public String getMailboxName() {
+        return mailboxName;
+    }
+
+}

Propchange: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/request/GetACLRequest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/response/ACLResponse.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/response/ACLResponse.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/response/ACLResponse.java
 (added)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/response/ACLResponse.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,91 @@
+/****************************************************************
+ * 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.imap.message.response;
+
+import java.util.Map.Entry;
+
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.display.CharsetUtil;
+import org.apache.james.imap.api.message.response.ImapResponseMessage;
+import org.apache.james.mailbox.MailboxACL;
+import org.apache.james.mailbox.MailboxACL.MailboxACLEntryKey;
+import org.apache.james.mailbox.MailboxACL.MailboxACLRights;
+
+/**
+ * ACL Response.
+ * 
+ */
+public final class ACLResponse implements ImapResponseMessage {
+    private final MailboxACL acl;
+
+    private final String mailboxName;
+
+    public ACLResponse(String mailboxName, MailboxACL acl) {
+        super();
+        //FIXME encodeModifiedUTF7 invocations should probably be moved to 
org.apache.james.imap.encode.ImapResponseComposer analogically to 
org.apache.james.imap.decode.ImapRequestLineReader.mailbox() 
+        this.mailboxName = CharsetUtil.encodeModifiedUTF7(mailboxName);
+        this.acl = acl;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof ACLResponse) {
+            ACLResponse other = (ACLResponse) o;
+            return this.acl == other.acl || (this.acl != null && 
this.acl.equals(other.acl))
+                    && this.mailboxName == other.mailboxName || 
(this.mailboxName != null && this.mailboxName.equals(other.mailboxName))
+                    ;
+        }
+        return false;
+    }
+
+    public MailboxACL getAcl() {
+        return acl;
+    }
+
+    public String getMailboxName() {
+        return mailboxName;
+    }
+
+    @Override
+    public int hashCode() {
+        final int PRIME = 31;
+        return PRIME * acl.hashCode() + mailboxName.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder()
+        .append(ImapConstants.ACL_RESPONSE_NAME)
+        .append(' ')
+        .append(mailboxName);
+        
+        for (Entry<MailboxACLEntryKey, MailboxACLRights> en : 
acl.getEntries().entrySet()) {
+            result
+            .append(' ')
+            .append(en.getKey().toString())
+            .append(' ')
+            .append(en.getValue().toString())
+            ;
+        }
+        
+        return result.toString();
+    };
+
+}

Propchange: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/message/response/ACLResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java?rev=1237290&r1=1237289&r2=1237290&view=diff
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
 (original)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java
 Sun Jan 29 13:52:44 2012
@@ -84,7 +84,11 @@ public class DefaultProcessorChain {
         final UnselectProcessor unselectProcessor = new 
UnselectProcessor(startTLSProcessor, mailboxManager, statusResponseFactory);
 
         final CompressProcessor compressProcessor = new 
CompressProcessor(unselectProcessor, statusResponseFactory);
-        final EnableProcessor enableProcessor = new 
EnableProcessor(compressProcessor, mailboxManager, statusResponseFactory);
+        
+        final GetACLProcessor getACLProcessor = new 
GetACLProcessor(compressProcessor, mailboxManager, statusResponseFactory);
+        
+        final EnableProcessor enableProcessor = new 
EnableProcessor(getACLProcessor, mailboxManager, statusResponseFactory);
+        
         // add for QRESYNC
         enableProcessor.addProcessor(selectProcessor);
         
@@ -108,6 +112,8 @@ public class DefaultProcessorChain {
         
         // Add to announce QRESYNC
         capabilityProcessor.addProcessor(selectProcessor);
+        
+        capabilityProcessor.addProcessor(getACLProcessor);
 
         return enableProcessor;
 

Added: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
 (added)
+++ 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,113 @@
+/****************************************************************
+ * 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.imap.processor;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapSessionUtils;
+import org.apache.james.imap.api.display.HumanReadableText;
+import org.apache.james.imap.api.message.response.StatusResponseFactory;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.message.request.GetACLRequest;
+import org.apache.james.imap.message.response.ACLResponse;
+import org.apache.james.mailbox.InsufficientRightsException;
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxNotFoundException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.MetaData;
+import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
+import org.apache.james.mailbox.SimpleMailboxACL.Rfc4314Rights;
+
+/**
+ * GETACL Processor.
+ * 
+ */
+public class GetACLProcessor extends AbstractMailboxProcessor<GetACLRequest> 
implements CapabilityImplementingProcessor {
+
+    private static final List<String> CAPABILITIES = 
Collections.singletonList(ImapConstants.SUPPORTS_ACL);
+
+    public GetACLProcessor(ImapProcessor next, MailboxManager mailboxManager, 
StatusResponseFactory factory) {
+        super(GetACLRequest.class, next, mailboxManager, factory);
+    }
+
+    @Override
+    protected void doProcess(GetACLRequest message, ImapSession session, 
String tag, ImapCommand command, Responder responder) {
+
+        final MailboxManager mailboxManager = getMailboxManager();
+        final MailboxSession mailboxSession = 
ImapSessionUtils.getMailboxSession(session);
+        try {
+            String mailboxName = message.getMailboxName();
+
+            MessageManager messageManager = 
mailboxManager.getMailbox(buildFullPath(session, mailboxName), mailboxSession);
+
+            /*
+             * RFC 4314 section 6.
+             * An implementation MUST make sure the ACL commands themselves do
+             * not give information about mailboxes with appropriately
+             * restricted ACLs. For example, when a user agent executes a 
GETACL
+             * command on a mailbox that the user has no permission to LIST, 
the
+             * server would respond to that request with the same error that
+             * would be used if the mailbox did not exist, thus revealing no
+             * existence information, much less the mailbox’s ACL.
+             */
+            if (!messageManager.hasRight(Rfc4314Rights.l_Lookup_RIGHT, 
mailboxSession)) {
+                throw new MailboxNotFoundException(mailboxName);
+            }
+
+            /* RFC 4314 section 4. */
+            if (!messageManager.hasRight(Rfc4314Rights.a_Administer_RIGHT, 
mailboxSession)) {
+                throw new InsufficientRightsException();
+            }
+
+            MetaData metaData = messageManager.getMetaData(false, 
mailboxSession, FetchGroup.NO_COUNT);
+            ACLResponse aclResponse = new ACLResponse(mailboxName, 
metaData.getACL());
+            responder.respond(aclResponse);
+            okComplete(command, tag, responder);
+            // FIXME should we send unsolicited responses here?
+            // unsolicitedResponses(session, responder, false);
+        } catch (MailboxNotFoundException e) {
+            no(command, tag, responder, HumanReadableText.MAILBOX_NOT_FOUND);
+        } catch (InsufficientRightsException e) {
+            // FIXME: be more specific in the human readable text.
+            no(command, tag, responder, 
HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
+        } catch (MailboxException e) {
+            // FIXME: be more specific in the human readable text.
+            no(command, tag, responder, 
HumanReadableText.GENERIC_FAILURE_DURING_PROCESSING);
+        }
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.james.imap.processor.CapabilityImplementingProcessor#
+     * 
getImplementedCapabilities(org.apache.james.imap.api.process.ImapSession)
+     */
+    public List<String> getImplementedCapabilities(ImapSession session) {
+        return CAPABILITIES;
+    }
+
+}

Propchange: 
james/protocols/trunk/imap/src/main/java/org/apache/james/imap/processor/GetACLProcessor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java
 (added)
+++ 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,217 @@
+/****************************************************************
+ * 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.imap.processor;
+
+import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.ImapSessionState;
+import org.apache.james.imap.api.ImapSessionUtils;
+import org.apache.james.imap.api.message.response.StatusResponse;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.api.process.ImapProcessor.Responder;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.message.request.GetACLRequest;
+import org.apache.james.imap.message.response.ACLResponse;
+import org.apache.james.imap.message.response.UnpooledStatusResponseFactory;
+import org.apache.james.mailbox.MailboxACL;
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxNotFoundException;
+import org.apache.james.mailbox.MailboxPath;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MessageManager.MetaData;
+import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
+import org.apache.james.mailbox.SimpleMailboxACL;
+import org.apache.james.mailbox.SimpleMailboxACL.Rfc4314Rights;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * GetACLProcessor Test.
+ * 
+ */
+@RunWith(JMock.class)
+public class GetACLProcessorTest {
+
+    private static final String MAILBOX_NAME = ImapConstants.INBOX_NAME;
+    private static final String USER_1 = "user1";
+
+    ImapSession imapSessionStub;
+    MailboxManager mailboxManagerStub;
+    MailboxSession mailboxSessionStub;
+    MessageManager messageManagerStub;
+    MetaData metaDataStub;
+    Mockery mockery = new JUnit4Mockery();
+    GetACLRequest namespaceRequest;
+    UnpooledStatusResponseFactory statusResponseFactory;
+    GetACLProcessor subject;
+    User user1Stub;
+
+    private Expectations prepareRightsExpectations() throws MailboxException {
+        return new Expectations() {
+            {
+
+                
allowing(imapSessionStub).getAttribute(ImapSessionUtils.MAILBOX_SESSION_ATTRIBUTE_SESSION_KEY);
+                will(returnValue(mailboxSessionStub));
+
+                allowing(imapSessionStub).getState();
+                will(returnValue(ImapSessionState.AUTHENTICATED));
+
+                allowing(mailboxSessionStub).getUser();
+                will(returnValue(user1Stub));
+
+                allowing(user1Stub).getUserName();
+                will(returnValue(USER_1));
+
+                
allowing(mailboxManagerStub).startProcessingRequest(with(same(mailboxSessionStub)));
+                
allowing(mailboxManagerStub).endProcessingRequest(with(same(mailboxSessionStub)));
+
+                
allowing(messageManagerStub).getMetaData(with(any(Boolean.class)), 
with(same(mailboxSessionStub)), with(any(FetchGroup.class)));
+                will(returnValue(metaDataStub));
+
+            }
+        };
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        statusResponseFactory = new UnpooledStatusResponseFactory();
+        mailboxManagerStub = mockery.mock(MailboxManager.class);
+        subject = new GetACLProcessor(mockery.mock(ImapProcessor.class), 
mailboxManagerStub, statusResponseFactory);
+        imapSessionStub = mockery.mock(ImapSession.class);
+        mailboxSessionStub = mockery.mock(MailboxSession.class);
+        user1Stub = mockery.mock(User.class);
+        messageManagerStub = mockery.mock(MessageManager.class);
+        metaDataStub = mockery.mock(MetaData.class);
+
+        namespaceRequest = new GetACLRequest("TAG", 
ImapCommand.anyStateCommand("Name"), MAILBOX_NAME);
+
+    }
+
+    @Test
+    public void testNoListRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        
expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)),
 expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        
expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)),
 expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new 
StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testNoAdminRight() throws Exception {
+
+        Expectations expectations = prepareRightsExpectations();
+        
expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)),
 expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+
+        
expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)),
 expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(false));
+
+        
expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)),
 expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new 
StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+
+    }
+    
+    @Test
+    public void testInexistentMailboxName() throws Exception {
+        Expectations expectations = prepareRightsExpectations();
+        
+        
expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)),
 expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.throwException(new 
MailboxNotFoundException(MAILBOX_NAME)));
+
+        mockery.checking(expectations);
+
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(new 
StatusResponseTypeMatcher(StatusResponse.Type.NO)));
+            }
+        });
+
+        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+    }
+
+    @Test
+    public void testSufficientRights() throws Exception {
+
+        final MailboxACL acl = SimpleMailboxACL.OWNER_FULL_ACL;
+
+        Expectations expectations = prepareRightsExpectations();
+        
+        
expectations.allowing(mailboxManagerStub).getMailbox(expectations.with(Expectations.any(MailboxPath.class)),
 expectations.with(Expectations.any(MailboxSession.class)));
+        expectations.will(Expectations.returnValue(messageManagerStub));
+        
+        
expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.l_Lookup_RIGHT)),
 expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+        
expectations.allowing(messageManagerStub).hasRight(expectations.with(Expectations.equal(Rfc4314Rights.a_Administer_RIGHT)),
 expectations.with(Expectations.same(mailboxSessionStub)));
+        expectations.will(Expectations.returnValue(true));
+        
+
+        expectations.allowing(metaDataStub).getACL();
+        expectations.will(Expectations.returnValue(acl));
+
+        mockery.checking(expectations);
+
+        final ACLResponse response = new ACLResponse(MAILBOX_NAME, acl);
+        final Responder responderMock = mockery.mock(Responder.class);
+        mockery.checking(new Expectations() {
+            {
+                oneOf(responderMock).respond(with(equal(response)));
+                oneOf(responderMock).respond(with(new 
StatusResponseTypeMatcher(StatusResponse.Type.OK)));
+            }
+        });
+
+        subject.doProcess(namespaceRequest, responderMock, imapSessionStub);
+    }
+
+}

Propchange: 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/GetACLProcessorTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/StatusResponseTypeMatcher.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/StatusResponseTypeMatcher.java?rev=1237290&view=auto
==============================================================================
--- 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/StatusResponseTypeMatcher.java
 (added)
+++ 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/StatusResponseTypeMatcher.java
 Sun Jan 29 13:52:44 2012
@@ -0,0 +1,62 @@
+/*
+ *   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.imap.processor;
+
+import org.apache.james.imap.api.message.response.StatusResponse;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+
+/**
+ * A matcher for {@link StatusResponse} objects, whereby only their
+ * serverResponseType field is significant. is significant.
+ * 
+ */
+public class StatusResponseTypeMatcher extends BaseMatcher<StatusResponse> {
+    private final 
org.apache.james.imap.api.message.response.StatusResponse.Type 
serverResponseType;
+
+    public 
StatusResponseTypeMatcher(org.apache.james.imap.api.message.response.StatusResponse.Type
 responseCode) {
+        super();
+        this.serverResponseType = responseCode;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.hamcrest.Matcher#matches(java.lang.Object)
+     */
+    public boolean matches(Object o) {
+        if (o instanceof StatusResponse) {
+            StatusResponse sr = (StatusResponse) o;
+            return this.serverResponseType.equals(sr.getServerResponseType());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.hamcrest.SelfDescribing#describeTo(org.hamcrest.Description)
+     */
+    public void describeTo(Description d) {
+        d.appendText(StatusResponse.class.getName());
+        d.appendText(" with serverResponseType.equals(" + 
serverResponseType.name() + ")");
+
+    }
+
+}
\ No newline at end of file

Propchange: 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/StatusResponseTypeMatcher.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
URL: 
http://svn.apache.org/viewvc/james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java?rev=1237290&r1=1237289&r2=1237290&view=diff
==============================================================================
--- 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
 (original)
+++ 
james/protocols/trunk/imap/src/test/java/org/apache/james/imap/processor/base/MailboxEventAnalyserTest.java
 Sun Jan 29 13:52:44 2012
@@ -43,6 +43,7 @@ import org.apache.james.imap.api.process
 import org.apache.james.mailbox.BadCredentialsException;
 import org.apache.james.mailbox.Content;
 import org.apache.james.mailbox.Headers;
+import org.apache.james.mailbox.MailboxACL.MailboxACLRight;
 import org.apache.james.mailbox.MailboxException;
 import org.apache.james.mailbox.MailboxListener;
 import org.apache.james.mailbox.MailboxManager;
@@ -295,6 +296,12 @@ public class MailboxEventAnalyserTest {
 
                 }
                 
+                
+                public boolean hasRight(MailboxACLRight right, MailboxSession 
session) throws MailboxException {
+                    //FIXME: somebody should approve that always true is the 
proper result here
+                    return true;
+                }
+
             };
         }
         



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

Reply via email to