001/*
002 * (C) Copyright 2019 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 *     Salem Aouana
018 */
019
020package org.nuxeo.ecm.platform.oauth2.tokens;
021
022import static java.util.Objects.requireNonNull;
023import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
024import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
025import static org.nuxeo.ecm.platform.oauth2.tokens.NuxeoOAuth2Token.KEY_NUXEO_LOGIN;
026import static org.nuxeo.ecm.platform.oauth2.tokens.NuxeoOAuth2Token.KEY_SERVICE_NAME;
027
028import java.util.List;
029import java.util.stream.Collectors;
030
031import org.apache.commons.lang3.StringUtils;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.NuxeoException;
034import org.nuxeo.ecm.core.api.NuxeoPrincipal;
035import org.nuxeo.ecm.core.query.sql.model.Predicates;
036import org.nuxeo.ecm.core.query.sql.model.QueryBuilder;
037import org.nuxeo.ecm.directory.Session;
038import org.nuxeo.ecm.directory.api.DirectoryService;
039import org.nuxeo.ecm.platform.oauth2.enums.NuxeoOAuth2TokenType;
040import org.nuxeo.runtime.api.Framework;
041import org.nuxeo.runtime.model.DefaultComponent;
042
043/**
044 * The implementation that manages the oauth2 tokens in Nuxeo.
045 *
046 * @since 11.1
047 */
048public class OAuth2TokenServiceImpl extends DefaultComponent implements OAuth2TokenService {
049
050    public static final String TOKEN_DIR = "oauth2Tokens";
051
052    @Override
053    public List<NuxeoOAuth2Token> getTokens(NuxeoPrincipal principal) {
054        return findTokens(getQueryBuilder(null, null), principal);
055    }
056
057    @Override
058    public List<NuxeoOAuth2Token> getTokens(String nxuser) {
059        requireNonNull(nxuser, "nxuser cannot be null");
060        return findTokens(getQueryBuilder(nxuser, null));
061    }
062
063    @Override
064    public List<NuxeoOAuth2Token> getTokens(NuxeoOAuth2TokenType type, NuxeoPrincipal principal) {
065        requireNonNull(type, "oAuth2TokenType cannot be null");
066        return findTokens(getQueryBuilder(null, type), principal);
067    }
068
069    @Override
070    public List<NuxeoOAuth2Token> getTokens(String nxuser, NuxeoOAuth2TokenType type) {
071        requireNonNull(nxuser, "nxuser cannot be null");
072        requireNonNull(type, "oAuth2TokenType cannot be null");
073
074        return findTokens(getQueryBuilder(nxuser, type));
075    }
076
077    @Override
078    public List<NuxeoOAuth2Token> search(String query, NuxeoPrincipal principal) {
079        return findTokens(getQueryBuilder(query), principal);
080    }
081
082    protected List<NuxeoOAuth2Token> findTokens(QueryBuilder queryBuilder) {
083        return findTokens(queryBuilder, null);
084    }
085
086    protected List<NuxeoOAuth2Token> findTokens(QueryBuilder queryBuilder, NuxeoPrincipal principal) {
087        if (principal != null) {
088            checkPermission(principal);
089        }
090        return Framework.doPrivileged(() -> {
091            DirectoryService ds = Framework.getService(DirectoryService.class);
092            try (Session session = ds.open(TOKEN_DIR)) {
093                List<DocumentModel> documents = session.query(queryBuilder, false);
094                return documents.stream().map(NuxeoOAuth2Token::new).collect(Collectors.toList());
095            }
096        });
097    }
098
099    protected void checkPermission(NuxeoPrincipal principal) {
100        if (!principal.isAdministrator()) {
101            throw new NuxeoException("You do not have permissions to perform this operation.", SC_FORBIDDEN);
102        }
103    }
104
105    protected QueryBuilder getQueryBuilder(String query) {
106        if (StringUtils.isEmpty(query)) {
107            throw new NuxeoException("query is required", SC_BAD_REQUEST);
108        }
109
110        String match = String.format("%%%s%%", query);
111        return new QueryBuilder().predicate(
112                Predicates.or(Predicates.like(KEY_NUXEO_LOGIN, match), Predicates.like(KEY_SERVICE_NAME, match)));
113
114    }
115
116    protected QueryBuilder getQueryBuilder(String nxuser, NuxeoOAuth2TokenType type) {
117        QueryBuilder queryBuilder = new QueryBuilder();
118
119        if (nxuser != null) {
120            queryBuilder.predicate(Predicates.eq(NuxeoOAuth2Token.KEY_NUXEO_LOGIN, nxuser));
121        }
122        if (type != null) {
123            queryBuilder.predicate(type.getPredicate());
124        }
125        return queryBuilder;
126    }
127}