Class: Oauth3
- Inherits:
-
Object
- Object
- Oauth3
- Defined in:
- lib/oauth3.rb
Instance Method Summary collapse
- #authorization_code_callback(params) ⇒ Object
- #authorize_url(provider_uri, params) ⇒ Object
- #get_directive(provider_uri) ⇒ Object
- #get_oauth2_client(provider_uri) ⇒ Object
- #get_profile(provider_uri, token) ⇒ Object
- #get_resource(provider_uri, token, path) ⇒ Object
- #get_state(state) ⇒ Object
- #get_token(provider_uri, code) ⇒ Object
-
#initialize(registrar, options = {}) ⇒ Oauth3
constructor
A new instance of Oauth3.
- #normalize_provider_uri(uri) ⇒ Object
- #random_string ⇒ Object
- #validate_state(provider_uri, state) ⇒ Object
Constructor Details
#initialize(registrar, options = {}) ⇒ Oauth3
Returns a new instance of Oauth3.
17 18 19 20 21 22 23 24 25 |
# File 'lib/oauth3.rb', line 17 def initialize(registrar, ={}) # make sure all options for the OAuth module and faraday # pass all the way down @options = @states = {} @providers = {} @clients = {} @registrar = registrar end |
Instance Method Details
#authorization_code_callback(params) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/oauth3.rb', line 104 def (params) # TODO needs error handling function to make this DRY server_state = params[:state] or params[:server_state] if not server_state if params[:error] return params else return { error: "E_NO_STATE", error_description: "provider_did_not_return_state" } end end = @@oauth3.get_state(server_state) if not return { error: "E_INVALID_SERVER_STATE", error_description: "server_state_missing_or_expired" } end # TODO provider_uri should not be necessary because we have state # (but I don't think oauth3.html implements that completely yet) # meta_state = { created_at, provider_uri, params } browser_params = [:params].merge({ provider_uri: [:provider_uri] }) if not browser_params browser_params = { error: "E_SANITY_FAIL", error_description: "sanity fail: server_state missing browser_params" } params.delete(:state) return params.merge(browser_params) end browser_state = browser_params[:state] or browser_params[:browser_state] if not browser_state browser_params[:error] = "E_INVALID_BROWSER_STATE" browser_params[:error_description] = "server_state missing or expired" return browser_params end # TODO decide on one or the other. Favor explicit to avoid confusion? result_params = { browser_state: browser_state, state: browser_state } if params[:error] params.delete(:state) return params.merge(result_params) end code = params[:code] if not code result_params[:error] = "E_INVALID_BROWSER_STATE" result_params[:error_description] = "state_missing_or_expired" params.delete(:state) return params.merge(result_params) end provider_uri = browser_params[:provider_uri] if token = @@oauth3.get_token(provider_uri, code).token result_params[:access_token] = token end # Note in the future the server will send back # granted_scopes=foo,bar,baz,etc # expires_at=2015-04-01T12:30:00.000Z # app_scoped_id=<<default-account-app-scoped-id>> params.delete(:state) params.merge(result_params) end |
#authorize_url(provider_uri, params) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/oauth3.rb', line 84 def (provider_uri, params) provider_uri = @@oauth3.normalize_provider_uri(provider_uri) = @options[:authorization_code_callback_uri] || @options[:redirect_uri] rnd = random_string() @states[rnd] = { created_at: Time.now, provider_uri: provider_uri, params: params } get_oauth2_client(provider_uri).auth_code.({ # Note that no parameters can be passed tothis redirect # It is required to be verbatim for Facebook and probably many other providers redirect_uri: , scope: params[:scope], state: rnd }) end |
#get_directive(provider_uri) ⇒ Object
31 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 |
# File 'lib/oauth3.rb', line 31 def get_directive(provider_uri) if @providers[provider_uri] # and @directive.timestamp < 1.day.old return @providers[provider_uri][:directive] end registration = @registrar.get(provider_uri) dynamic = true if registration and registration['directives'] directives = registration['directives'] dynamic = false else # TODO if there's no prefix (https://), add it first # TODO if the directive is stale, refresh it http = HTTPClient.new() response = http.get_content("#{provider_uri}/oauth3.json") directives = JSON.parse(response) end @providers[provider_uri] = { provider_uri: provider_uri, directive: directives, timestamp: Time.now, dynamic: dynamic } @providers[provider_uri][:directive] end |
#get_oauth2_client(provider_uri) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/oauth3.rb', line 59 def get_oauth2_client(provider_uri) # TODO refresh the client when refreshing the directive if @clients[provider_uri] return @clients[provider_uri] end = @options.dup [:site] = "" [:authorize_url] = get_directive(provider_uri)['authorization_dialog']['url'] [:token_url] = get_directive(provider_uri)['access_token']['url'] token_method = (get_directive(provider_uri)['access_token']['method'] || 'POST').downcase.to_sym [:token_method] = token_method @clients[provider_uri] = OAuth2::Client.new( @registrar.get(provider_uri)['id'], @registrar.get(provider_uri)['secret'], ) end |
#get_profile(provider_uri, token) ⇒ Object
182 183 184 185 |
# File 'lib/oauth3.rb', line 182 def get_profile(provider_uri, token) url = get_directive(provider_uri)['profile']['url'] OAuth2::AccessToken.new(get_oauth2_client(provider_uri), token).get(url) end |
#get_resource(provider_uri, token, path) ⇒ Object
187 188 189 190 |
# File 'lib/oauth3.rb', line 187 def get_resource(provider_uri, token, path) url = get_directive(provider_uri)['api_base_url'] OAuth2::AccessToken.new(get_oauth2_client(provider_uri), token).get("#{url}/#{path}") end |
#get_state(state) ⇒ Object
167 168 169 |
# File 'lib/oauth3.rb', line 167 def get_state(state) @states.delete(state) end |
#get_token(provider_uri, code) ⇒ Object
176 177 178 179 180 |
# File 'lib/oauth3.rb', line 176 def get_token(provider_uri, code) get_oauth2_client(provider_uri).auth_code.get_token(code, { redirect_uri: @options[:authorization_code_callback_uri] }) end |
#normalize_provider_uri(uri) ⇒ Object
27 28 29 |
# File 'lib/oauth3.rb', line 27 def normalize_provider_uri(uri) 'https://' + uri.gsub(/https?:\/\//, '') end |
#random_string ⇒ Object
80 81 82 |
# File 'lib/oauth3.rb', line 80 def random_string (0...50).map { ('a'..'z').to_a[rand(26)] }.join end |
#validate_state(provider_uri, state) ⇒ Object
171 172 173 174 |
# File 'lib/oauth3.rb', line 171 def validate_state(provider_uri, state) # TODO delete stale states @states[state] end |