1   /*
2    * Copyright 2019 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package com.linecorp.centraldogma.server.metadata;
18  
19  import static com.google.common.base.MoreObjects.firstNonNull;
20  import static java.util.Objects.requireNonNull;
21  
22  import javax.annotation.Nullable;
23  
24  import com.fasterxml.jackson.annotation.JsonCreator;
25  import com.fasterxml.jackson.annotation.JsonProperty;
26  import com.google.common.base.MoreObjects;
27  import com.google.common.base.Objects;
28  
29  import com.linecorp.centraldogma.internal.Util;
30  
31  /**
32   * Specifies details of an application token.
33   */
34  public final class Token extends AbstractAppIdentity {
35  
36      /**
37       * A secret which is used to access an HTTP API.
38       */
39      @Nullable
40      private final String secret;
41  
42      Token(String appId, String secret, boolean isSystemAdmin, boolean allowGuestAccess,
43            UserAndTimestamp creation) {
44          super(appId, AppIdentityType.TOKEN, isSystemAdmin, allowGuestAccess, creation, null, null);
45          this.secret = Util.validateFileName(secret, "secret");
46      }
47  
48      /**
49       * Creates a new instance.
50       */
51      @JsonCreator
52      public Token(@JsonProperty("appId") String appId,
53                   @JsonProperty("secret") String secret,
54                   @JsonProperty("systemAdmin") boolean isSystemAdmin,
55                   @JsonProperty("allowGuestAccess") @Nullable Boolean allowGuestAccess,
56                   @JsonProperty("creation") UserAndTimestamp creation,
57                   @JsonProperty("deactivation") @Nullable UserAndTimestamp deactivation,
58                   @JsonProperty("deletion") @Nullable UserAndTimestamp deletion) {
59          super(appId, AppIdentityType.TOKEN, isSystemAdmin,
60                // Allow guest access by default for backward compatibility.
61                firstNonNull(allowGuestAccess, true),
62                requireNonNull(creation, "creation"),
63                deactivation,
64                deletion);
65          this.secret = Util.validateFileName(secret, "secret");
66      }
67  
68      private Token(String appId, boolean isSystemAdmin, boolean allowGuestAccess, UserAndTimestamp creation,
69                    @Nullable UserAndTimestamp deactivation, @Nullable UserAndTimestamp deletion) {
70          super(appId, AppIdentityType.TOKEN, isSystemAdmin, allowGuestAccess,
71                requireNonNull(creation, "creation"), deactivation, deletion);
72          secret = null;
73      }
74  
75      /**
76       * Returns the ID of the application.
77       */
78      @Override
79      @JsonProperty("appId")
80      public String appId() {
81          return id();
82      }
83  
84      /**
85       * Returns the secret.
86       */
87      @Nullable
88      @JsonProperty
89      public String secret() {
90          return secret;
91      }
92  
93      /**
94       * Returns a new {@link Token} instance without its secret.
95       */
96      public Token withoutSecret() {
97          return new Token(id(), isSystemAdmin(), allowGuestAccess(), creation(), deactivation(), deletion());
98      }
99  
100     /**
101      * Returns a new {@link Token} instance with the specified system admin flag.
102      * This method must be called by the token whose secret is not null.
103      */
104     @Override
105     public Token withSystemAdmin(boolean isSystemAdmin) {
106         if (isSystemAdmin == isSystemAdmin()) {
107             return this;
108         }
109         final String secret = secret();
110         assert secret != null;
111         return new Token(id(), secret, isSystemAdmin, allowGuestAccess(), creation(),
112                          deactivation(), deletion());
113     }
114 
115     @Override
116     public int hashCode() {
117         return Objects.hashCode(super.hashCode(), secret);
118     }
119 
120     @Override
121     public boolean equals(Object o) {
122         if (!super.equals(o)) {
123             return false;
124         }
125 
126         final Token that = (Token) o;
127         return Objects.equal(secret, that.secret);
128     }
129 
130     @Override
131     void addProperties(MoreObjects.ToStringHelper helper) {
132         // Do not add "secret" to prevent it from logging.
133     }
134 }