001/*
002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.shell.automation.cmds;
020
021import java.util.HashMap;
022
023import jline.ANSIBuffer;
024
025import org.nuxeo.ecm.automation.client.model.DocRef;
026import org.nuxeo.shell.Argument;
027import org.nuxeo.shell.Command;
028import org.nuxeo.shell.Context;
029import org.nuxeo.shell.Parameter;
030import org.nuxeo.shell.Shell;
031import org.nuxeo.shell.ShellConsole;
032import org.nuxeo.shell.ShellException;
033import org.nuxeo.shell.automation.DocRefCompletor;
034import org.nuxeo.shell.automation.RemoteContext;
035import org.nuxeo.shell.automation.Scripting;
036import org.nuxeo.shell.utils.ANSICodes;
037import org.nuxeo.shell.utils.StringUtils;
038
039/**
040 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
041 */
042@Command(name = "perms", help = "Set or view permissions on a document")
043public class Perms implements Runnable {
044
045    @Context
046    protected RemoteContext ctx;
047
048    @Parameter(name = "-acl", hasValue = true, help = "The ACL to view or modify. If not specified then in write mode the local ACL is used and in view mode all acls are printed.")
049    protected String acl;
050
051    @Parameter(name = "-remove", hasValue = false, help = "Remove the given acl.")
052    protected boolean remove;
053
054    @Parameter(name = "-grant", hasValue = true, help = "If used the ACL will be modified by granting the specified permission on the specified user. The grant value format is \"user:permission\".")
055    protected String grant;
056
057    @Parameter(name = "-deny", hasValue = true, help = "If used the ACL will be modified by denying the specified permission on the specified user. The deny value format is \"user:permission\".")
058    protected String deny;
059
060    @Argument(name = "doc", index = 0, required = false, completor = DocRefCompletor.class, help = "The target document. If not specified the current document is used. To use UID references prefix them with 'doc:'.")
061    protected String path;
062
063    public void run() {
064        DocRef doc = ctx.resolveRef(path);
065        try {
066            if (remove) {
067                removeAcl(doc, acl);
068            } else if (grant == null && deny == null) {
069                printAcl(ctx.getShell().getConsole(), doc, acl);
070            } else {
071                setAcl(doc, acl, grant, deny);
072            }
073        } catch (ShellException e) {
074            throw e;
075        } catch (Exception e) {
076            throw new ShellException("Failed to set property on " + doc, e);
077        }
078    }
079
080    protected void setAcl(DocRef doc, String acl, String grant, String deny) throws Exception {
081        if (grant != null) {
082            String[] ar = StringUtils.split(grant, ':', true);
083            if (ar.length != 2) {
084                throw new ShellException("Invalid grant expression: Use \"user:permission\".");
085            }
086            ctx.getDocumentService().setPermission(doc, ar[0], ar[1], acl, true);
087        }
088        if (deny != null) {
089            String[] ar = StringUtils.split(deny, ':', true);
090            if (ar.length != 2) {
091                throw new ShellException("Invalid deny expression: Use \"user:permission\".");
092            }
093            ctx.getDocumentService().setPermission(doc, ar[0], ar[1], acl, false);
094        }
095    }
096
097    protected void printAcl(ShellConsole console, DocRef doc, String acl) throws Exception {
098        HashMap<String, Object> ctx = new HashMap<String, Object>();
099        if (acl != null) {
100            ctx.put("acl", acl);
101        }
102        ctx.put("ref", doc.toString());
103        String result = Scripting.run("scripts/printAcl.groovy", ctx, null);
104        ANSIBuffer buf = Shell.get().newANSIBuffer();
105        ANSICodes.appendTemplate(buf, result, false);
106        console.println(buf.toString());
107    }
108
109    protected void removeAcl(DocRef doc, String acl) throws Exception {
110        if (acl == null) {
111            throw new ShellException("In remove mode the -acl parameter is required!");
112        }
113        ctx.getDocumentService().removeAcl(doc, acl);
114    }
115
116}