Class: Triannon::ApplicationController

Inherits:
ActionController::Base
  • Object
show all
Defined in:
app/controllers/triannon/application_controller.rb

Instance Method Summary collapse

Instance Method Details

#access_token_dataObject

Extract access login data for a session.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'app/controllers/triannon/application_controller.rb', line 28

def access_token_data
  @access_data ||= begin
    data = {}
    auth = request.headers['Authorization']
    if auth.nil? || auth !~ /^Bearer/ || session[:access_token].nil?
      access_token_error
    else
      token = auth.split.last
      if token == session[:access_token]
        timestamp, salt = session[:access_data]
        if access_token_expired?(timestamp)
          access_token_error('Access token expired')
        else
          key = ActiveSupport::KeyGenerator.new(timestamp).generate_key(salt)
          crypt = ActiveSupport::MessageEncryptor.new(key)
          data = crypt.decrypt_and_verify(token)
        end
      else
        access_token_error('Access code does not match login session')
      end
    end
    data
  rescue
    access_token_error('Failed to validate access code')
    data
  end
end

#access_token_error(msg = nil, status = 401) ⇒ Object

Issue an access token error



67
68
69
70
71
72
73
74
75
# File 'app/controllers/triannon/application_controller.rb', line 67

def access_token_error(msg=nil, status=401)
  msg ||= 'Access token required'
  err = {
    error: 'invalidRequest',
    errorDescription: msg,
    errorUri: 'http://image-auth.iiif.io/api/image/2.1/authentication.html#access-token-service'
  }
  json_response(err, status)
end

#access_token_expired?(timestamp) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
# File 'app/controllers/triannon/application_controller.rb', line 56

def access_token_expired?(timestamp)
  elapsed = Time.now.to_i - timestamp.to_i  # sec since code was issued
  elapsed >= Triannon.config[:access_token_expiry]
end

#access_token_generate(data) ⇒ Object

construct and encrypt an access token, using login data save the token into session



17
18
19
20
21
22
23
24
# File 'app/controllers/triannon/application_controller.rb', line 17

def access_token_generate(data)
  timestamp = Time.now.to_i.to_s # seconds since epoch
  salt  = SecureRandom.base64(64)
  key   = ActiveSupport::KeyGenerator.new(timestamp).generate_key(salt)
  crypt = ActiveSupport::MessageEncryptor.new(key)
  session[:access_data] = [timestamp, salt]
  session[:access_token] = crypt.encrypt_and_sign(data)
end

#access_token_valid?Boolean

decrypt, parse and validate access token

Returns:

  • (Boolean)


62
63
64
# File 'app/controllers/triannon/application_controller.rb', line 62

def access_token_valid?
  not access_token_data.empty?
end

#json_response(data, status) ⇒ Object

Parameters:

  • data (Hash)

    Hash.to_json is rendered

  • status (Integer)

    HTTP status code



84
85
86
# File 'app/controllers/triannon/application_controller.rb', line 84

def json_response(data, status)
  render json: data.to_json, content_type: json_type_accepted, status: status
end

#json_type_acceptedObject

Response content type to match an HTTP accept type for JSON formats



89
90
91
# File 'app/controllers/triannon/application_controller.rb', line 89

def json_type_accepted
  mime_type_from_accept(['application/json', 'text/x-json', 'application/jsonrequest'])
end