LCOV - code coverage report
Current view: top level - auth/oauth - OAuthRealm.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 12 40 30.0 %
Date: 2022-11-19 15:00:39 Functions: 2 6 33.3 %

          Line data    Source code
       1             : // Copyright (C) 2015 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.auth.oauth;
      16             : 
      17             : import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_EXTERNAL;
      18             : 
      19             : import com.google.common.base.Strings;
      20             : import com.google.gerrit.entities.Account;
      21             : import com.google.gerrit.extensions.auth.oauth.OAuthLoginProvider;
      22             : import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo;
      23             : import com.google.gerrit.extensions.client.AccountFieldName;
      24             : import com.google.gerrit.extensions.registration.DynamicMap;
      25             : import com.google.gerrit.server.account.AbstractRealm;
      26             : import com.google.gerrit.server.account.AccountException;
      27             : import com.google.gerrit.server.account.AccountManager;
      28             : import com.google.gerrit.server.account.AuthRequest;
      29             : import com.google.gerrit.server.account.externalids.ExternalId;
      30             : import com.google.gerrit.server.config.GerritServerConfig;
      31             : import com.google.inject.Inject;
      32             : import com.google.inject.Singleton;
      33             : import java.io.IOException;
      34             : import java.util.Collection;
      35             : import java.util.HashSet;
      36             : import java.util.Set;
      37             : import org.eclipse.jgit.lib.Config;
      38             : 
      39             : @Singleton
      40             : public class OAuthRealm extends AbstractRealm {
      41             :   private final DynamicMap<OAuthLoginProvider> loginProviders;
      42             :   private final Set<AccountFieldName> editableAccountFields;
      43             : 
      44             :   @Inject
      45           1 :   OAuthRealm(DynamicMap<OAuthLoginProvider> loginProviders, @GerritServerConfig Config config) {
      46           1 :     this.loginProviders = loginProviders;
      47           1 :     this.editableAccountFields = new HashSet<>();
      48             :     // User name should be always editable, because not all OAuth providers
      49             :     // expose them
      50           1 :     editableAccountFields.add(AccountFieldName.USER_NAME);
      51           1 :     if (config.getBoolean("oauth", null, "allowEditFullName", false)) {
      52           0 :       editableAccountFields.add(AccountFieldName.FULL_NAME);
      53             :     }
      54           1 :     if (config.getBoolean("oauth", null, "allowRegisterNewEmail", false)) {
      55           0 :       editableAccountFields.add(AccountFieldName.REGISTER_NEW_EMAIL);
      56             :     }
      57           1 :   }
      58             : 
      59             :   @Override
      60             :   public boolean allowsEdit(AccountFieldName field) {
      61           0 :     return editableAccountFields.contains(field);
      62             :   }
      63             : 
      64             :   /**
      65             :    * Authenticates with the {@link OAuthLoginProvider} specified in the authentication request.
      66             :    *
      67             :    * <p>{@link AccountManager} calls this method without password if authenticity of the user has
      68             :    * already been established. In that case we can skip the authentication request to the {@code
      69             :    * OAuthLoginService}.
      70             :    *
      71             :    * @param who the authentication request.
      72             :    * @return the authentication request with resolved email address and display name in case the
      73             :    *     authenticity of the user could be established; otherwise {@code who} is returned unchanged.
      74             :    * @throws AccountException if the authentication request with the OAuth2 server failed or no
      75             :    *     {@code OAuthLoginProvider} was available to handle the request.
      76             :    */
      77             :   @Override
      78             :   public AuthRequest authenticate(AuthRequest who) throws AccountException {
      79           0 :     if (Strings.isNullOrEmpty(who.getPassword())) {
      80           0 :       return who;
      81             :     }
      82             : 
      83           0 :     if (Strings.isNullOrEmpty(who.getAuthPlugin())
      84           0 :         || Strings.isNullOrEmpty(who.getAuthProvider())) {
      85           0 :       throw new AccountException("Cannot authenticate");
      86             :     }
      87           0 :     OAuthLoginProvider loginProvider =
      88           0 :         loginProviders.get(who.getAuthPlugin(), who.getAuthProvider());
      89           0 :     if (loginProvider == null) {
      90           0 :       throw new AccountException("Cannot authenticate");
      91             :     }
      92             : 
      93             :     OAuthUserInfo userInfo;
      94             :     try {
      95           0 :       userInfo = loginProvider.login(who.getUserName().orElse(null), who.getPassword());
      96           0 :     } catch (IOException e) {
      97           0 :       throw new AccountException("Cannot authenticate", e);
      98           0 :     }
      99           0 :     if (userInfo == null) {
     100           0 :       throw new AccountException("Cannot authenticate");
     101             :     }
     102           0 :     if (!Strings.isNullOrEmpty(userInfo.getEmailAddress())
     103           0 :         && (!who.getUserName().isPresent() || !allowsEdit(AccountFieldName.REGISTER_NEW_EMAIL))) {
     104           0 :       who.setEmailAddress(userInfo.getEmailAddress());
     105             :     }
     106           0 :     if (!Strings.isNullOrEmpty(userInfo.getDisplayName())
     107           0 :         && (Strings.isNullOrEmpty(who.getDisplayName())
     108           0 :             || !allowsEdit(AccountFieldName.FULL_NAME))) {
     109           0 :       who.setDisplayName(userInfo.getDisplayName());
     110             :     }
     111           0 :     return who;
     112             :   }
     113             : 
     114             :   @Override
     115           0 :   public void onCreateAccount(AuthRequest who, Account account) {}
     116             : 
     117             :   @Override
     118             :   public Account.Id lookup(String accountName) {
     119           0 :     return null;
     120             :   }
     121             : 
     122             :   @Override
     123             :   public boolean accountBelongsToRealm(Collection<ExternalId> externalIds) {
     124           1 :     for (ExternalId id : externalIds) {
     125           1 :       if (id.isScheme(SCHEME_EXTERNAL)) {
     126           1 :         return true;
     127             :       }
     128           1 :     }
     129           1 :     return false;
     130             :   }
     131             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750