Class: Urbanairship::Oauth

Inherits:
Object
  • Object
show all
Defined in:
lib/urbanairship/oauth.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_id:, key:, assertion_private_key:, ip_addresses: [], scopes: [], oauth_server: Urbanairship.configuration.oauth_server) ⇒ Object

Initialize Oauth class

Parameters:

  • client_id (String)

    The Client ID found when creating Oauth credentials in the dashboard.

  • key (String)

    The app key for the project.

  • assertion_private_key (String)

    The private key found when creating Oauth credentials in the dashboard. Used for assertion token auth.

  • ip_addresses (Array<String>) (defaults to: [])

    A list of CIDR representations of valid IP addresses to which the issued token is restricted. Example: [‘24.20.40.0/22’, ‘34.17.3.0/22’]

  • scopes (Array<String>) (defaults to: [])

    A list of scopes to which the issued token will be entitled. Example: [‘psh’, ‘lst’]

  • oauth_server (String) (defaults to: Urbanairship.configuration.oauth_server)

    The server to send Oauth token requests to. By default is ‘oauth2.asnapius.com’, but can be set to ‘oauth2.asnapieu.com’ if using the EU server.



18
19
20
21
22
23
24
25
26
27
# File 'lib/urbanairship/oauth.rb', line 18

def initialize(client_id:, key:, assertion_private_key:, ip_addresses: [], scopes: [], oauth_server: Urbanairship.configuration.oauth_server)
  @grant_type = 'client_credentials'
  @client_id = client_id
  @assertion_private_key = assertion_private_key
  @ip_addresses = ip_addresses
  @scopes = scopes
  @sub = "app:#{key}"
  @oauth_server = oauth_server
  @token = nil
end

Instance Attribute Details

#assertion_private_keyObject

Returns the value of attribute assertion_private_key.



7
8
9
# File 'lib/urbanairship/oauth.rb', line 7

def assertion_private_key
  @assertion_private_key
end

#client_idObject

Returns the value of attribute client_id.



7
8
9
# File 'lib/urbanairship/oauth.rb', line 7

def client_id
  @client_id
end

#ip_addressesObject

Returns the value of attribute ip_addresses.



7
8
9
# File 'lib/urbanairship/oauth.rb', line 7

def ip_addresses
  @ip_addresses
end

#oauth_serverObject

Returns the value of attribute oauth_server.



7
8
9
# File 'lib/urbanairship/oauth.rb', line 7

def oauth_server
  @oauth_server
end

#scopesObject

Returns the value of attribute scopes.



7
8
9
# File 'lib/urbanairship/oauth.rb', line 7

def scopes
  @scopes
end

#subObject

Returns the value of attribute sub.



7
8
9
# File 'lib/urbanairship/oauth.rb', line 7

def sub
  @sub
end

Instance Method Details

#build_assertion_jwtString

Build an assertion JWT

Returns:

  • (String)

    Assertion JWT to be used when requesting an Oauth token from Airship servers.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/urbanairship/oauth.rb', line 89

def build_assertion_jwt
  assertion_expiration = 61
  private_key = OpenSSL::PKey::EC.new(@assertion_private_key)

  headers = {
    alg: 'ES384',
    kid: @client_id
  }

  claims = {
    aud: "https://#{@oauth_server}/token",
    exp: Time.now.to_i + assertion_expiration,
    iat: Time.now.to_i,
    iss: @client_id,
    nonce: SecureRandom.uuid,
    sub: @sub
  }

  claims[:scope] = @scopes.join(' ') if @scopes.any?
  claims[:ipaddr] = @ip_addresses.join(' ') if @ip_addresses.any?

  JWT.encode(claims, private_key, 'ES384', headers)
end

#get_tokenString

Get an Oauth token from Airship Oauth servers.

Returns:

  • (String)

    JSON web token to be used in further Airship API requests.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/urbanairship/oauth.rb', line 32

def get_token
  unless @token.nil?
    decoded_jwt = JWT.decode(@token, nil, false)
    current_time = Time.now.to_i
    expiry_time = decoded_jwt[0]['exp']

    if current_time < expiry_time
      return @token
    end
  end

  assertion_jwt = build_assertion_jwt

  url = "https://#{@oauth_server}/token"
  headers = {
    'Host': @oauth_server,
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': 'application/json'
  }

  params = {
    method: :post,
    url: url,
    headers: headers,
    payload: {
      grant_type: @grant_type,
      assertion: assertion_jwt
    },
    timeout: 60
  }

  retries = 0
  max_retries = 3
  begin
    response = RestClient::Request.execute(params)
    @token = JSON.parse(response.body)['access_token']
    return @token
  rescue RestClient::ExceptionWithResponse => e
    if [400, 401, 406].include?(e.response.code)
      raise e
    else
      retries += 1
      if retries <= max_retries
        sleep(retries ** 2)
        retry
      else
        new_error = RestClient::Exception.new(e.response, e.response.code)
        new_error.message = "failed after 3 attempts with error: #{e}"
        raise new_error
      end
    end
  end
end

#verify_public_key(key_id) ⇒ String

Verify a public key

Parameters:

  • key_id (String)

    The key ID (‘kid’) found in the header when decoding an Oauth token granted from Airship’s servers.

Returns:

  • (String)

    The public key associated with the Key ID.



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/urbanairship/oauth.rb', line 117

def verify_public_key(key_id)
  url = "https://#{@oauth_server}/verify/public_key/#{key_id}"

  headers = {
    'Host': @oauth_server,
    'Accept': 'text/plain'
  }

  response = RestClient.get(url, headers)
  response.body
end