001/*
002 * (C) Copyright 2006-2017 Nuxeo (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 *     vpasquier
019 *     slacoin
020 */
021package org.nuxeo.ecm.automation.server;
022
023import java.security.Principal;
024import java.util.ArrayList;
025import java.util.List;
026
027import javax.servlet.http.HttpServletRequest;
028import javax.ws.rs.ext.MessageBodyReader;
029import javax.ws.rs.ext.MessageBodyWriter;
030
031import org.nuxeo.ecm.automation.core.Constants;
032import org.nuxeo.ecm.core.api.NuxeoPrincipal;
033import org.nuxeo.runtime.model.ComponentContext;
034import org.nuxeo.runtime.model.DefaultComponent;
035
036/**
037 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
038 */
039public class AutomationServerComponent extends DefaultComponent implements AutomationServer {
040
041    /**
042     * @since 10.3
043     */
044    public static final String XP_BINDINGS = "bindings";
045
046    /**
047     * @since 10.3
048     */
049    public static final String XP_MARSHALLER = "marshallers";
050
051    protected List<Class<? extends MessageBodyWriter<?>>> writers = new ArrayList<>();
052
053    protected List<Class<? extends MessageBodyReader<?>>> readers = new ArrayList<>();
054
055    @Override
056    public void start(ComponentContext context) {
057        super.start(context);
058        List<MarshallerDescriptor> marshallers = getDescriptors(XP_MARSHALLER);
059        marshallers.forEach(m -> {
060            writers.addAll(m.writers);
061            readers.addAll(m.readers);
062        });
063    }
064
065    @Override
066    public void stop(ComponentContext context) throws InterruptedException {
067        super.stop(context);
068        writers.clear();
069        readers.clear();
070    }
071
072    @Override
073    public <T> T getAdapter(Class<T> adapter) {
074        if (AutomationServer.class.isAssignableFrom(adapter)) {
075            return adapter.cast(this);
076        }
077        return null;
078    }
079
080    @Override
081    public RestBinding getOperationBinding(String name) {
082        return getDescriptor(XP_BINDINGS, name);
083    }
084
085    @Override
086    public RestBinding getChainBinding(String name) {
087        return getDescriptor(XP_BINDINGS, Constants.CHAIN_ID_PREFIX + name);
088    }
089
090    @Override
091    public RestBinding[] getBindings() {
092        List<RestBinding> descriptors = getDescriptors(XP_BINDINGS);
093        return descriptors.toArray(new RestBinding[0]);
094    }
095
096    @Override
097    public synchronized void addBinding(RestBinding binding) {
098        register(XP_BINDINGS, binding);
099    }
100
101    @Override
102    public synchronized RestBinding removeBinding(RestBinding binding) {
103        return unregister(XP_BINDINGS, binding) ? binding : null;
104    }
105
106    @Override
107    public boolean accept(String name, boolean isChain, HttpServletRequest req) {
108        if (isChain) {
109            name = Constants.CHAIN_ID_PREFIX + name;
110        }
111        RestBinding binding = getDescriptor(XP_BINDINGS, name);
112        if (binding != null) {
113            if (binding.isDisabled) {
114                return false;
115            }
116            if (binding.isSecure && !req.isSecure()) {
117                return false;
118            }
119            Principal principal = req.getUserPrincipal();
120
121            if (binding.isAdministrator || binding.hasGroups()) {
122                if (principal instanceof NuxeoPrincipal) {
123                    NuxeoPrincipal np = (NuxeoPrincipal) principal;
124                    if (binding.isAdministrator && np.isAdministrator()) {
125                        return true;
126                    }
127                    if (binding.hasGroups()) {
128                        for (String group : binding.groups) {
129                            if (np.isMemberOf(group)) {
130                                return true;
131                            }
132                        }
133                    }
134                }
135                return false;
136            }
137        }
138        return true;
139    }
140
141    @Override
142    public List<Class<? extends MessageBodyWriter<?>>> getWriters() {
143        return writers;
144    }
145
146    @Override
147    public List<Class<? extends MessageBodyReader<?>>> getReaders() {
148        return readers;
149    }
150
151}