Line data Source code
1 : // Copyright (C) 2016 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.httpd.auth.restapi; 16 : 17 : import com.google.common.flogger.FluentLogger; 18 : import com.google.gerrit.auth.oauth.OAuthTokenCache; 19 : import com.google.gerrit.common.Nullable; 20 : import com.google.gerrit.extensions.auth.oauth.OAuthToken; 21 : import com.google.gerrit.extensions.restapi.AuthException; 22 : import com.google.gerrit.extensions.restapi.ResourceNotFoundException; 23 : import com.google.gerrit.extensions.restapi.Response; 24 : import com.google.gerrit.extensions.restapi.RestReadView; 25 : import com.google.gerrit.server.CurrentUser; 26 : import com.google.gerrit.server.account.AccountResource; 27 : import com.google.gerrit.server.config.CanonicalWebUrl; 28 : import com.google.inject.Inject; 29 : import com.google.inject.Provider; 30 : import com.google.inject.Singleton; 31 : import java.net.URI; 32 : import java.net.URISyntaxException; 33 : 34 : @Singleton 35 : public class GetOAuthToken implements RestReadView<AccountResource> { 36 138 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 37 : 38 : private static final String BEARER_TYPE = "bearer"; 39 : 40 : private final Provider<CurrentUser> self; 41 : private final OAuthTokenCache tokenCache; 42 : private final Provider<String> canonicalWebUrlProvider; 43 : 44 : @Inject 45 : GetOAuthToken( 46 : Provider<CurrentUser> self, 47 : OAuthTokenCache tokenCache, 48 138 : @CanonicalWebUrl Provider<String> urlProvider) { 49 138 : this.self = self; 50 138 : this.tokenCache = tokenCache; 51 138 : this.canonicalWebUrlProvider = urlProvider; 52 138 : } 53 : 54 : @Override 55 : public Response<OAuthTokenInfo> apply(AccountResource rsrc) 56 : throws AuthException, ResourceNotFoundException { 57 0 : if (!self.get().hasSameAccountId(rsrc.getUser())) { 58 0 : throw new AuthException("not allowed to get access token"); 59 : } 60 0 : OAuthToken accessToken = tokenCache.get(rsrc.getUser().getAccountId()); 61 0 : if (accessToken == null) { 62 0 : throw new ResourceNotFoundException(); 63 : } 64 0 : OAuthTokenInfo accessTokenInfo = new OAuthTokenInfo(); 65 0 : accessTokenInfo.username = rsrc.getUser().getUserName().orElse(null); 66 0 : accessTokenInfo.resourceHost = getHostName(canonicalWebUrlProvider.get()); 67 0 : accessTokenInfo.accessToken = accessToken.getToken(); 68 0 : accessTokenInfo.providerId = accessToken.getProviderId(); 69 0 : accessTokenInfo.expiresAt = Long.toString(accessToken.getExpiresAt()); 70 0 : accessTokenInfo.type = BEARER_TYPE; 71 0 : return Response.ok(accessTokenInfo); 72 : } 73 : 74 : @Nullable 75 : private static String getHostName(String canonicalWebUrl) { 76 0 : if (canonicalWebUrl == null) { 77 0 : logger.atSevere().log( 78 : "No canonicalWebUrl defined in gerrit.config, OAuth may not work properly"); 79 0 : return null; 80 : } 81 : 82 : try { 83 0 : return new URI(canonicalWebUrl).getHost(); 84 0 : } catch (URISyntaxException e) { 85 0 : logger.atSevere().withCause(e).log("Invalid canonicalWebUrl '%s'", canonicalWebUrl); 86 0 : return null; 87 : } 88 : } 89 : 90 0 : public static class OAuthTokenInfo { 91 : public String username; 92 : public String resourceHost; 93 : public String accessToken; 94 : public String providerId; 95 : public String expiresAt; 96 : public String type; 97 : } 98 : }