LCOV - code coverage report
Current view: top level - entities - Account.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 47 48 97.9 %
Date: 2022-11-19 15:00:39 Functions: 19 20 95.0 %

          Line data    Source code
       1             : // Copyright (C) 2008 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.entities;
      16             : 
      17             : import static com.google.gerrit.entities.RefNames.REFS_DRAFT_COMMENTS;
      18             : import static com.google.gerrit.entities.RefNames.REFS_STARRED_CHANGES;
      19             : import static com.google.gerrit.entities.RefNames.REFS_USERS;
      20             : 
      21             : import com.google.auto.value.AutoValue;
      22             : import com.google.common.primitives.Ints;
      23             : import com.google.gerrit.common.Nullable;
      24             : import com.google.gerrit.extensions.client.DiffPreferencesInfo;
      25             : import java.time.Instant;
      26             : import java.util.Optional;
      27             : 
      28             : /**
      29             :  * Information about a single user.
      30             :  *
      31             :  * <p>A user may have multiple identities they can use to login to Gerrit (see ExternalId), but in
      32             :  * such cases they always map back to a single Account entity.
      33             :  *
      34             :  * <p>Entities "owned" by an Account (that is, their primary key contains the {@link Account.Id} key
      35             :  * as part of their key structure):
      36             :  *
      37             :  * <ul>
      38             :  *   <li>ExternalId: OpenID identities and email addresses known to be registered to this user.
      39             :  *       Multiple records can exist when the user has more than one public identity, such as a work
      40             :  *       and a personal email address.
      41             :  *   <li>AccountSshKey: user's public SSH keys, for authentication through the internal SSH daemon.
      42             :  *       One record per SSH key uploaded by the user, keys are checked in random order until a match
      43             :  *       is found.
      44             :  *   <li>{@link DiffPreferencesInfo}: user's preferences for rendering side-to-side and unified diff
      45             :  * </ul>
      46             :  */
      47             : @AutoValue
      48         153 : public abstract class Account {
      49             : 
      50             :   /** Placeholder for indicating an account-id that does not correspond to any local account */
      51         161 :   public static final Id UNKNOWN_ACCOUNT_ID = id(0);
      52             : 
      53             :   public static Id id(int id) {
      54         161 :     return new AutoValue_Account_Id(id);
      55             :   }
      56             : 
      57             :   /** Key local to Gerrit to identify a user. */
      58             :   @AutoValue
      59         161 :   public abstract static class Id implements Comparable<Id> {
      60             :     /** Parse an Account.Id out of a string representation. */
      61             :     public static Optional<Id> tryParse(String str) {
      62          94 :       return Optional.ofNullable(Ints.tryParse(str)).map(Account::id);
      63             :     }
      64             : 
      65             :     @Nullable
      66             :     public static Id fromRef(String name) {
      67         152 :       if (name == null) {
      68           1 :         return null;
      69             :       }
      70         152 :       if (name.startsWith(REFS_USERS)) {
      71         152 :         return fromRefPart(name.substring(REFS_USERS.length()));
      72         152 :       } else if (name.startsWith(REFS_DRAFT_COMMENTS)) {
      73           4 :         return parseAfterShardedRefPart(name.substring(REFS_DRAFT_COMMENTS.length()));
      74         152 :       } else if (name.startsWith(REFS_STARRED_CHANGES)) {
      75          11 :         return parseAfterShardedRefPart(name.substring(REFS_STARRED_CHANGES.length()));
      76             :       }
      77         152 :       return null;
      78             :     }
      79             : 
      80             :     /**
      81             :      * Parse an Account.Id out of a part of a ref-name.
      82             :      *
      83             :      * @param name a ref name with the following syntax: {@code "34/1234..."}. We assume that the
      84             :      *     caller has trimmed any prefix.
      85             :      */
      86             :     @Nullable
      87             :     public static Id fromRefPart(String name) {
      88         152 :       Integer id = RefNames.parseShardedRefPart(name);
      89         152 :       return id != null ? Account.id(id) : null;
      90             :     }
      91             : 
      92             :     @Nullable
      93             :     public static Id parseAfterShardedRefPart(String name) {
      94          12 :       Integer id = RefNames.parseAfterShardedRefPart(name);
      95          12 :       return id != null ? Account.id(id) : null;
      96             :     }
      97             : 
      98             :     /**
      99             :      * Parse an Account.Id out of the last part of a ref name.
     100             :      *
     101             :      * <p>The input is a ref name of the form {@code ".../1234"}, where the suffix is a non-sharded
     102             :      * account ID. Ref names using a sharded ID should use {@link #fromRefPart(String)} instead for
     103             :      * greater safety.
     104             :      *
     105             :      * @param name ref name
     106             :      * @return account ID, or null if not numeric.
     107             :      */
     108             :     @Nullable
     109             :     public static Id fromRefSuffix(String name) {
     110           3 :       Integer id = RefNames.parseRefSuffix(name);
     111           3 :       return id != null ? Account.id(id) : null;
     112             :     }
     113             : 
     114             :     abstract int id();
     115             : 
     116             :     public int get() {
     117         158 :       return id();
     118             :     }
     119             : 
     120             :     @Override
     121             :     public final int compareTo(Id o) {
     122          68 :       return Integer.compare(id(), o.id());
     123             :     }
     124             : 
     125             :     @Override
     126             :     public final String toString() {
     127         153 :       return Integer.toString(get());
     128             :     }
     129             :   }
     130             : 
     131             :   public abstract Id id();
     132             : 
     133             :   /** Date and time the user registered with the review server. */
     134             :   public abstract Instant registeredOn();
     135             : 
     136             :   /** Full name of the user ("Given-name Surname" style). */
     137             :   @Nullable
     138             :   public abstract String fullName();
     139             : 
     140             :   /** Optional display name of the user to be shown in the UI. */
     141             :   @Nullable
     142             :   public abstract String displayName();
     143             : 
     144             :   /** Email address the user prefers to be contacted through. */
     145             :   @Nullable
     146             :   public abstract String preferredEmail();
     147             : 
     148             :   /**
     149             :    * Is this user inactive? This is used to avoid showing some users (eg. former employees) in
     150             :    * auto-suggest.
     151             :    */
     152             :   public abstract boolean inactive();
     153             : 
     154             :   /** The user-settable status of this account (e.g. busy, OOO, available) */
     155             :   @Nullable
     156             :   public abstract String status();
     157             : 
     158             :   /** ID of the user branch from which the account was read. */
     159             :   @Nullable
     160             :   public abstract String metaId();
     161             : 
     162             :   /**
     163             :    * Create a new account.
     164             :    *
     165             :    * @param newId unique id, see {@link com.google.gerrit.server.notedb.Sequences#nextAccountId()}.
     166             :    * @param registeredOn when the account was registered.
     167             :    */
     168             :   public static Account.Builder builder(Account.Id newId, Instant registeredOn) {
     169         153 :     return new AutoValue_Account.Builder()
     170         153 :         .setInactive(false)
     171         153 :         .setId(newId)
     172         153 :         .setRegisteredOn(registeredOn);
     173             :   }
     174             : 
     175             :   /**
     176             :    * Formats an account name.
     177             :    *
     178             :    * <p>The return value goes into NoteDb commits and audit logs, so it should not be changed.
     179             :    *
     180             :    * <p>This method deliberately does not use {@code Anonymous Coward} because it can be changed
     181             :    * using a {@code gerrit.config} option which is a problem for NoteDb commits that still refer to
     182             :    * a previously defined value.
     183             :    *
     184             :    * @return the fullname, if present, otherwise the preferred email, if present, as a last resort a
     185             :    *     generic string containing the accountId.
     186             :    */
     187             :   public String getName() {
     188         152 :     if (fullName() != null) {
     189         144 :       return fullName();
     190             :     }
     191          23 :     if (preferredEmail() != null) {
     192           6 :       return preferredEmail();
     193             :     }
     194          23 :     return getName(id());
     195             :   }
     196             : 
     197             :   public static String getName(Account.Id accountId) {
     198          23 :     return "GerritAccount #" + accountId.get();
     199             :   }
     200             : 
     201             :   /**
     202             :    * Get the name and email address.
     203             :    *
     204             :    * <p>Example output:
     205             :    *
     206             :    * <ul>
     207             :    *   <li>{@code A U. Thor <author@example.com>}: full populated
     208             :    *   <li>{@code A U. Thor (12)}: missing email address
     209             :    *   <li>{@code Anonymous Coward <author@example.com>}: missing name
     210             :    *   <li>{@code Anonymous Coward (12)}: missing name and email address
     211             :    * </ul>
     212             :    */
     213             :   public String getNameEmail(String anonymousCowardName) {
     214          23 :     String name = fullName() != null ? fullName() : anonymousCowardName;
     215          23 :     StringBuilder b = new StringBuilder();
     216          23 :     b.append(name);
     217          23 :     if (preferredEmail() != null) {
     218          23 :       b.append(" <");
     219          23 :       b.append(preferredEmail());
     220          23 :       b.append(">");
     221             :     } else {
     222           6 :       b.append(" (");
     223           6 :       b.append(id().get());
     224           6 :       b.append(")");
     225             :     }
     226          23 :     return b.toString();
     227             :   }
     228             : 
     229             :   public boolean isActive() {
     230         150 :     return !inactive();
     231             :   }
     232             : 
     233             :   public abstract Builder toBuilder();
     234             : 
     235             :   @AutoValue.Builder
     236         153 :   public abstract static class Builder {
     237             :     public abstract Id id();
     238             : 
     239             :     abstract Builder setId(Id id);
     240             : 
     241             :     public abstract Instant registeredOn();
     242             : 
     243             :     abstract Builder setRegisteredOn(Instant registeredOn);
     244             : 
     245             :     @Nullable
     246             :     public abstract String fullName();
     247             : 
     248             :     public abstract Builder setFullName(String fullName);
     249             : 
     250             :     @Nullable
     251             :     public abstract String displayName();
     252             : 
     253             :     public abstract Builder setDisplayName(String displayName);
     254             : 
     255             :     @Nullable
     256             :     public abstract String preferredEmail();
     257             : 
     258             :     public abstract Builder setPreferredEmail(String preferredEmail);
     259             : 
     260             :     public abstract boolean inactive();
     261             : 
     262             :     public abstract Builder setInactive(boolean inactive);
     263             : 
     264             :     public Builder setActive(boolean active) {
     265         151 :       return setInactive(!active);
     266             :     }
     267             : 
     268             :     @Nullable
     269             :     public abstract String status();
     270             : 
     271             :     public abstract Builder setStatus(String status);
     272             : 
     273             :     @Nullable
     274             :     public abstract String metaId();
     275             : 
     276             :     public abstract Builder setMetaId(@Nullable String metaId);
     277             : 
     278             :     public abstract Account build();
     279             :   }
     280             : 
     281             :   @Override
     282             :   public final String toString() {
     283           0 :     return getName();
     284             :   }
     285             : }

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