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.oauth;
020
021import java.io.IOException;
022import java.util.Objects;
023
024import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
025import com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest;
026import com.google.api.client.auth.oauth2.Credential;
027import com.google.api.client.auth.oauth2.Credential.AccessMethod;
028import com.google.api.client.http.GenericUrl;
029import com.google.api.client.http.HttpExecuteInterceptor;
030import com.google.api.client.http.HttpTransport;
031import com.google.api.client.json.JsonFactory;
032
033/**
034 * We need to add some hook on {@link AuthorizationCodeFlow} as OneDrive for Business needs the resource parameter for
035 * token and refresh token requests. Furthermore their response don't follow OAuth standard for expires_in field. See
036 * https://github.com/google/google-oauth-java-client/issues/62
037 * 
038 * @since 8.2
039 */
040public class OneDriveAuthorizationCodeFlow extends AuthorizationCodeFlow {
041
042    private static final String RESOURCE_PARAMETER = "resource";
043
044    private final String businessResource;
045
046    protected OneDriveAuthorizationCodeFlow(Builder builder) {
047        super(builder);
048        businessResource = Objects.requireNonNull(builder.businessResource);
049    }
050
051    @Override
052    public AuthorizationCodeTokenRequest newTokenRequest(String authorizationCode) {
053        OneDriveAuthorizationCodeTokenRequest tokenRequest = new OneDriveAuthorizationCodeTokenRequest(getTransport(),
054                getJsonFactory(), new GenericUrl(getTokenServerEncodedUrl()), authorizationCode);
055        tokenRequest.set(RESOURCE_PARAMETER, businessResource);
056        return tokenRequest.setClientAuthentication(getClientAuthentication())
057                           .setRequestInitializer(getRequestInitializer())
058                           .setScopes(getScopes());
059    }
060
061    @Override
062    public Credential loadCredential(String userId) throws IOException {
063        return new OneDriveCredential(super.loadCredential(userId), businessResource);
064    }
065
066    public static class Builder extends AuthorizationCodeFlow.Builder {
067
068        String businessResource;
069
070        public Builder(AccessMethod method, HttpTransport transport, JsonFactory jsonFactory,
071                GenericUrl tokenServerUrl, HttpExecuteInterceptor clientAuthentication, String clientId,
072                String authorizationServerEncodedUrl) {
073            super(method, transport, jsonFactory, tokenServerUrl, clientAuthentication, clientId,
074                    authorizationServerEncodedUrl);
075        }
076
077        @Override
078        public OneDriveAuthorizationCodeFlow build() {
079            return new OneDriveAuthorizationCodeFlow(this);
080        }
081
082        public Builder setBusinessResource(String businessResource) {
083            this.businessResource = Objects.requireNonNull(businessResource);
084            return this;
085        }
086
087    }
088
089}