001/*
002 * (C) Copyright 2016 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 *     Kevin Leturc
018 */
019package org.nuxeo.ecm.liveconnect.onedrive;
020
021import java.io.IOException;
022import java.util.Optional;
023import java.util.function.Function;
024
025import org.nuxeo.ecm.liveconnect.core.AbstractLiveConnectOAuth2ServiceProvider;
026import org.nuxeo.ecm.liveconnect.onedrive.oauth.OneDriveAuthorizationCodeFlow;
027import org.nuxeo.onedrive.client.OneDriveAPI;
028import org.nuxeo.onedrive.client.OneDriveBasicAPI;
029import org.nuxeo.onedrive.client.OneDriveBusinessAPI;
030import org.nuxeo.onedrive.client.OneDriveEmailAccount;
031
032import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
033import com.google.api.client.auth.oauth2.BearerToken;
034import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
035import com.google.api.client.auth.oauth2.Credential;
036import com.google.api.client.http.GenericUrl;
037import com.google.api.client.http.HttpExecuteInterceptor;
038
039/**
040 * @since 8.2
041 */
042public class OneDriveOAuth2ServiceProvider extends AbstractLiveConnectOAuth2ServiceProvider {
043
044    @Override
045    protected String getUserEmail(String accessToken) throws IOException {
046        OneDriveAPI api = getAPIInitializer().apply(accessToken);
047        return OneDriveEmailAccount.getCurrentUserEmailAccount(api);
048    }
049
050    protected Optional<String> getOneDriveForBusinessResource() {
051        GenericUrl tokenServerUrl = new GenericUrl(getTokenServerURL());
052        return Optional.ofNullable((String) tokenServerUrl.getFirst("resource")).map(
053                resource -> resource.replaceAll("\\\\/", "/"));
054    }
055
056    /**
057     * Returns the {@link OneDriveAPI} initializer which takes an access token.
058     *
059     * @return the {@link OneDriveAPI} initializer which takes an access token.
060     */
061    public Function<String, OneDriveAPI> getAPIInitializer() {
062        Optional<String> businessResourceURL = getOneDriveForBusinessResource();
063        if (businessResourceURL.isPresent()) {
064            return accessToken -> new OneDriveBusinessAPI(businessResourceURL.get(), accessToken);
065        }
066        return OneDriveBasicAPI::new;
067    }
068
069    @Override
070    public AuthorizationCodeFlow getAuthorizationCodeFlow() {
071        Optional<String> businessResource = getOneDriveForBusinessResource();
072        if (businessResource.isPresent()) {
073            String clientId = getClientId();
074            String clientSecret = getClientSecret();
075            String authorizationServerURL = getAuthorizationServerURL();
076
077            Credential.AccessMethod method = BearerToken.authorizationHeaderAccessMethod();
078            GenericUrl tokenServerUrl = new GenericUrl(getTokenServerURL());
079            HttpExecuteInterceptor clientAuthentication = new ClientParametersAuthentication(clientId, clientSecret);
080
081            return new OneDriveAuthorizationCodeFlow.Builder(method, HTTP_TRANSPORT, JSON_FACTORY, tokenServerUrl,
082                    clientAuthentication, clientId, authorizationServerURL).setBusinessResource(businessResource.get())
083                                                                           .setScopes(getScopes())
084                                                                           .setCredentialDataStore(
085                                                                                   getCredentialDataStore())
086                                                                           .build();
087        }
088        return super.getAuthorizationCodeFlow();
089    }
090
091}