490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksaclass AccessToken < ActiveRecord::Base
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa belongs_to :repository
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa attr_accessible :expiration, :token
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa
9b6c3209f4771089ca721d40cb96ff49b348e802Eugen Kuksa scope :expired, ->() { where('expiration <= ?', Time.now) }
5513a7cc4f5859d263e4cb66ae93e8dbfcf3681fEugen Kuksa scope :unexpired, ->() { where('expiration > ?', Time.now) }
5513a7cc4f5859d263e4cb66ae93e8dbfcf3681fEugen Kuksa
9b6c3209f4771089ca721d40cb96ff49b348e802Eugen Kuksa def self.destroy_expired
9b6c3209f4771089ca721d40cb96ff49b348e802Eugen Kuksa expired.find_each(&:destroy)
9b6c3209f4771089ca721d40cb96ff49b348e802Eugen Kuksa end
9b6c3209f4771089ca721d40cb96ff49b348e802Eugen Kuksa
fff4fdff482b9349911ce6365e9ac85b86a1fd5fEugen Kuksa def self.create_for(repository)
0050586f79baaf40dbe2cba81c239cad7939b283Eugen Kuksa # Although unlikely, the token could clash with another one. Generate tokens
0050586f79baaf40dbe2cba81c239cad7939b283Eugen Kuksa # until there is no conflict. This should converge extremely fast.
0050586f79baaf40dbe2cba81c239cad7939b283Eugen Kuksa access_token = nil
8b99a5dcb32ab1c94dd8bd214cf73a2bf9e15a92Eugen Kuksa while access_token.nil? || access_token.invalid?
fff4fdff482b9349911ce6365e9ac85b86a1fd5fEugen Kuksa access_token = build_for(repository)
0050586f79baaf40dbe2cba81c239cad7939b283Eugen Kuksa end
0050586f79baaf40dbe2cba81c239cad7939b283Eugen Kuksa access_token.save!
e5f7f6deff59acd41803916bae31e2cea5a23a91Eugen Kuksa AccessTokenDeletionWorker.perform_at(access_token.expiration)
0050586f79baaf40dbe2cba81c239cad7939b283Eugen Kuksa access_token
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa end
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa def self.fresh_expiration_date
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa Settings.access_token.expiration_minutes.minutes.from_now
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksa end
bae71386e6259d8b2f6941f21f37559b12a49b39Eugen Kuksa
fff4fdff482b9349911ce6365e9ac85b86a1fd5fEugen Kuksa def self.build_for(repository)
4c5fc55b01865cb3867ff4988c8316bcbe80aa02Eugen Kuksa AccessToken.new({
4c5fc55b01865cb3867ff4988c8316bcbe80aa02Eugen Kuksa repository: repository,
4c5fc55b01865cb3867ff4988c8316bcbe80aa02Eugen Kuksa expiration: fresh_expiration_date,
fff4fdff482b9349911ce6365e9ac85b86a1fd5fEugen Kuksa token: generate_token_string(repository)},
34d2f277614575f9a03071c000258f5681195044Eugen Kuksa {without_protection: true})
bae71386e6259d8b2f6941f21f37559b12a49b39Eugen Kuksa end
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa
fff4fdff482b9349911ce6365e9ac85b86a1fd5fEugen Kuksa def self.generate_token_string(repository)
c4acc9d036b3f375366c2609951a66837a520b7bEugen Kuksa id = [
fff4fdff482b9349911ce6365e9ac85b86a1fd5fEugen Kuksa repository.to_param,
c4acc9d036b3f375366c2609951a66837a520b7bEugen Kuksa Time.now.strftime('%Y-%m-%d-%H-%M-%S-%6N')
c4acc9d036b3f375366c2609951a66837a520b7bEugen Kuksa ].join('|')
c4acc9d036b3f375366c2609951a66837a520b7bEugen Kuksa Digest::SHA2.hexdigest(id)
c4acc9d036b3f375366c2609951a66837a520b7bEugen Kuksa end
c4acc9d036b3f375366c2609951a66837a520b7bEugen Kuksa
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa def to_s
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa token
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa end
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa def expired?
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa expiration <= Time.now
8020639d5f1f21a6b368d19f6e1b11040ae9696fEugen Kuksa end
490da89281b7ee019c87406fb8ce7359aff0932cEugen Kuksaend