personal_access_token.rb 1.6 KB
Newer Older
1
class PersonalAccessToken < ActiveRecord::Base
2
  include Expirable
3 4 5
  include TokenAuthenticatable
  add_authentication_token_field :token

6 7
  REDIS_EXPIRY_TIME = 3.minutes

8
  serialize :scopes, Array # rubocop:disable Cop/ActiveRecordSerialize
9

10 11
  belongs_to :user

12 13
  before_save :ensure_token

14
  scope :active, -> { where("revoked = false AND (expires_at >= NOW() OR expires_at IS NULL)") }
15
  scope :inactive, -> { where("revoked = true OR expires_at < NOW()") }
16 17
  scope :with_impersonation, -> { where(impersonation: true) }
  scope :without_impersonation, -> { where(impersonation: false) }
18

19
  validates :scopes, presence: true
20
  validate :validate_scopes
21

22 23
  after_initialize :set_default_scopes, if: :persisted?

24
  def revoke!
25
    update!(revoked: true)
26
  end
27 28 29 30

  def active?
    !revoked? && !expired?
  end
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
  def self.redis_getdel(user_id)
    Gitlab::Redis::SharedState.with do |redis|
      token = redis.get(redis_shared_state_key(user_id))
      redis.del(redis_shared_state_key(user_id))
      token
    end
  end

  def self.redis_store!(user_id, token)
    Gitlab::Redis::SharedState.with do |redis|
      redis.set(redis_shared_state_key(user_id), token, ex: REDIS_EXPIRY_TIME)
      token
    end
  end

47 48
  protected

49
  def validate_scopes
50
    unless revoked || scopes.all? { |scope| Gitlab::Auth.available_scopes.include?(scope.to_sym) }
51
      errors.add :scopes, "can only contain available scopes"
52 53
    end
  end
54 55 56 57

  def set_default_scopes
    self.scopes = Gitlab::Auth::DEFAULT_SCOPES if self.scopes.empty?
  end
58 59 60 61

  def self.redis_shared_state_key(user_id)
    "gitlab:personal_access_token:#{user_id}"
  end
62
end