content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.ambari.server.orm.entities;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  
  import jakarta.persistence.Basic;
  import jakarta.persistence.Column;
  import jakarta.persistence.Entity;
  import jakarta.persistence.EnumType;
  import jakarta.persistence.Enumerated;
  import jakarta.persistence.FetchType;
  import jakarta.persistence.GeneratedValue;
  import jakarta.persistence.GenerationType;
  import jakarta.persistence.Id;
  import jakarta.persistence.JoinColumn;
  import jakarta.persistence.ManyToOne;
  import jakarta.persistence.NamedQueries;
  import jakarta.persistence.NamedQuery;
  import jakarta.persistence.PrePersist;
  import jakarta.persistence.PreUpdate;
  import jakarta.persistence.Table;
  import jakarta.persistence.TableGenerator;
  
  import org.apache.ambari.server.security.authorization.UserAuthenticationType;
  import org.apache.commons.lang.builder.EqualsBuilder;
  import org.apache.commons.lang.builder.HashCodeBuilder;
  
  @Table(name = "user_authentication")
  @Entity
  @NamedQueries({
      @NamedQuery(name = "UserAuthenticationEntity.findAll",
          query = "SELECT entity FROM UserAuthenticationEntity entity"),
      @NamedQuery(name = "UserAuthenticationEntity.findByType",
          query = "SELECT entity FROM UserAuthenticationEntity entity where lower(entity.authenticationType)=lower(:authenticationType)"),
      @NamedQuery(name = "UserAuthenticationEntity.findByTypeAndKey",
          query = "SELECT entity FROM UserAuthenticationEntity entity where lower(entity.authenticationType)=lower(:authenticationType) and entity.authenticationKey=:authenticationKey"),
      @NamedQuery(name = "UserAuthenticationEntity.findByUser",
          query = "SELECT entity FROM UserAuthenticationEntity entity where entity.user.userId=:userId")
  })
  @TableGenerator(name = "user_authentication_id_generator",
      table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value"
      , pkColumnValue = "user_authentication_id_seq"
      , initialValue = 2
  )
  public class UserAuthenticationEntity {
  
    @Id
    @Column(name = "user_authentication_id")
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "user_authentication_id_generator")
    private Long userAuthenticationId;
  
    @Column(name = "authentication_type", nullable = false)
    @Enumerated(EnumType.STRING)
    @Basic
    private UserAuthenticationType authenticationType = UserAuthenticationType.LOCAL;
  
    @Column(name = "authentication_key")
    @Basic
    private String authenticationKey;
  
    @Column(name = "create_time", nullable = false)
    @Basic
    private long createTime;
  
    @Column(name = "update_time", nullable = false)
    @Basic
    private long updateTime ;
  
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", referencedColumnName = "user_id", nullable = false)
    private UserEntity user;
  
    public Long getUserAuthenticationId() {
      return userAuthenticationId;
    }
  
    public void setUserAuthenticationId(Long userAuthenticationId) {
      this.userAuthenticationId = userAuthenticationId;
    }
  
    public UserAuthenticationType getAuthenticationType() {
      return authenticationType;
    }
  
    public void setAuthenticationType(UserAuthenticationType authenticationType) {
      this.authenticationType = authenticationType;
    }
  
    public String getAuthenticationKey() {
      if (getAuthenticationType().equals(UserAuthenticationType.LOCAL)) {
        int firstCommaIndex = authenticationKey.indexOf(",");
        if (firstCommaIndex != -1) {
          return authenticationKey.substring(0, firstCommaIndex);
        }
      }
      return authenticationKey;
    }
  
    public String getFullAuthenticationKey() {
      return authenticationKey;
    }
  
    public void setAuthenticationKey(String authenticationKey) {
      this.authenticationKey = authenticationKey;
    }
  
    public void updateAuthenticationKey(String newAuthenticationKey, int historyCount) {
      if (this.authenticationKey == null || this.authenticationKey.isEmpty()) {
          this.authenticationKey = newAuthenticationKey;
      } else {
          String[] keys = this.authenticationKey.split(",");
          List<String> keyList = new ArrayList<>(Arrays.asList(keys));
          if (keyList.size() >= historyCount) {
              keyList = keyList.subList(0, historyCount - 1);
          }
          keyList.add(0, newAuthenticationKey);
          this.authenticationKey = String.join(",", keyList);
      }
  }
  
    public long getCreateTime() {
      return createTime;
    }
  
    public long getUpdateTime() {
      return updateTime;
    }
  
    /**
     * Get the relevant {@link UserEntity} associated with this {@link UserAuthenticationEntity}.
     *
     * @return a {@link UserEntity}
     */
    public UserEntity getUser() {
      return user;
    }
  
    /**
     * Set the relevant {@link UserEntity} associated with this {@link UserAuthenticationEntity}.
     *
     * @param user a {@link UserEntity}
     */
    public void setUser(UserEntity user) {
      this.user = user;
    }
  
    /**
     * Ensure the create time and update time are set properly when the record is created.
     */
    @PrePersist
    protected void onCreate() {
      final long now = System.currentTimeMillis();
      createTime = now;
      updateTime = now;
    }
  
    /**
     * Ensure the update time is set properly when the record is updated.
     */
    @PreUpdate
    protected void onUpdate() {
      updateTime = System.currentTimeMillis();
    }
  
    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      } else if (o == null || getClass() != o.getClass()) {
        return false;
      } else {
        UserAuthenticationEntity that = (UserAuthenticationEntity) o;
  
        EqualsBuilder equalsBuilder = new EqualsBuilder();
        equalsBuilder.append(userAuthenticationId, that.userAuthenticationId);
        equalsBuilder.append(authenticationType, that.authenticationType);
        equalsBuilder.append(authenticationKey, that.authenticationKey);
        equalsBuilder.append(createTime, that.createTime);
        equalsBuilder.append(updateTime, that.updateTime);
        return equalsBuilder.isEquals();
      }
    }
  
    @Override
    public int hashCode() {
      HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
      hashCodeBuilder.append(userAuthenticationId);
      hashCodeBuilder.append(authenticationType);
      hashCodeBuilder.append(authenticationKey);
      hashCodeBuilder.append(createTime);
      hashCodeBuilder.append(updateTime);
      return hashCodeBuilder.toHashCode();
    }
  }
  