Skip to content

Commit

Permalink
implement identity provider to allow loading of identities and fix so…
Browse files Browse the repository at this point in the history
…me issues
  • Loading branch information
Knerio committed Aug 18, 2024
1 parent 0196599 commit 0b96f20
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 52 deletions.
1 change: 1 addition & 0 deletions lib/code0/identities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require "httparty"

require_relative "identities/version"
require_relative "identities/identity_provider"
require_relative "identities/identity"
require_relative "identities/provider/base_oauth"
require_relative "identities/provider/microsoft"
Expand Down
31 changes: 31 additions & 0 deletions lib/code0/identities/identity_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module Code0
module Identities
class IdentityProvider
attr_reader :providers

def initialize
@providers = {}
end

def add_provider(provider_type, config_loader)
add_named_provider provider_type, provider_type, config_loader
end

def add_named_provider(provider_id, provider_type, config_loader)
provider = Identities::Provider.const_get(provider_type.capitalize).new(config_loader)
providers[provider_id] = provider
end

def load_identity(provider_id, params)
provider = providers[provider_id]
if provider.nil?
raise Error, "Provider with id '#{provider_id}' is not configured, did you forget to use add_provider"
end

provider.load_identity(params)
end
end
end
end
19 changes: 13 additions & 6 deletions lib/code0/identities/provider/base_oauth.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# frozen_string_literal: true

module Code0
module Identities
module Provider
class BaseOauth
attr_reader :config_loader

def initialize(config_loader)
@config_loader = config_loader
end

def authorization_url
raise NotImplementedError
Expand All @@ -19,8 +26,8 @@ def token_payload(code)
raise NotImplementedError
end


def load_identity(code)
def load_identity(**params)
code = params[:code]
token, token_type = access_token code

response = HTTParty.get(user_details_url,
Expand All @@ -39,9 +46,9 @@ def load_identity(code)
def access_token(code)
response = HTTParty.post(token_url,
body: URI.encode_www_form(token_payload(code)), headers: {
"Content-Type" => "application/x-www-form-urlencoded",
"Accept" => "application/json"
})
"Content-Type" => "application/x-www-form-urlencoded",
"Accept" => "application/json"
})

check_response response

Expand All @@ -62,4 +69,4 @@ def create_identity(*)
end
end
end
end
end
10 changes: 1 addition & 9 deletions lib/code0/identities/provider/discord.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ module Code0
module Identities
module Provider
class Discord < BaseOauth
attr_reader :config_loader

def initialize(config_loader)
@config_loader = config_loader
end

def token_url
"https://discord.com/api/oauth2/token"
end
Expand All @@ -20,8 +14,7 @@ def token_payload(code)
grant_type: "authorization_code",
redirect_uri: config[:redirect_uri],
client_id: config[:client_id],
client_secret: config[:client_secret]
}
client_secret: config[:client_secret] }
end

def user_details_url
Expand All @@ -33,7 +26,6 @@ def authorization_url
"https://discord.com/oauth2/authorize?client_id=#{config[:client_id]}&response_type=code&redirect_uri=#{URI.encode_uri_component(config[:redirect_uri])}&scope=identify+openid+email"
end


def create_identity(response, *)
body = response.parsed_response

Expand Down
13 changes: 2 additions & 11 deletions lib/code0/identities/provider/github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ module Code0
module Identities
module Provider
class Github < BaseOauth
attr_reader :config_loader

def initialize(config_loader)
@config_loader = config_loader
end

def token_url
"https://github.com/login/oauth/access_token"
end
Expand All @@ -19,8 +13,7 @@ def token_payload(code)
{ code: code,
redirect_uri: config[:redirect_uri],
client_id: config[:client_id],
client_secret: config[:client_secret]
}
client_secret: config[:client_secret] }
end

def user_details_url
Expand All @@ -33,7 +26,7 @@ def authorization_url
end

def private_email(access_token, token_type)
response = HTTParty.get(user_details_url + "/emails",
response = HTTParty.get("#{user_details_url}/emails",
headers: {
Authorization: "#{token_type} #{access_token}",
"Accept" => "application/json"
Expand All @@ -52,8 +45,6 @@ def create_identity(response, access_token, token_type)

email = private_email(access_token, token_type) if email.nil?



Identity.new(:github, identifier, username, email, nil, nil)
end
end
Expand Down
16 changes: 5 additions & 11 deletions lib/code0/identities/provider/gitlab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,13 @@ module Code0
module Identities
module Provider
class Gitlab < BaseOauth
attr_reader :config_loader

def initialize(config_loader)
@config_loader = config_loader
end

def base_url
config = config_loader.call
config[:base_url]
end

def token_url
base_url + "/oauth/token"
"#{base_url}/oauth/token"
end

def token_payload(code)
Expand All @@ -25,20 +19,20 @@ def token_payload(code)
grant_type: "authorization_code",
redirect_uri: config[:redirect_uri],
client_id: config[:client_id],
client_secret: config[:client_secret]
}
client_secret: config[:client_secret] }
end

def user_details_url
base_url + "/api/v4/user"
"#{base_url}/api/v4/user"
end

def authorization_url
config = config_loader.call
# rubocop:disable Layout/LineLength
base_url + "/oauth/authorize?client_id=#{config[:client_id]}&response_type=code&redirect_uri=#{URI.encode_uri_component(config[:redirect_uri])}&scope=read_user"
# rubocop:enable Layout/LineLength
end


def create_identity(response, *)
body = response.parsed_response

Expand Down
8 changes: 2 additions & 6 deletions lib/code0/identities/provider/google.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ module Code0
module Identities
module Provider
class Google < BaseOauth
attr_reader :config_loader

def initialize(config_loader)
@config_loader = config_loader
end

def base_url
"https://accounts.google.com"
end
Expand All @@ -35,7 +29,9 @@ def user_details_url

def authorization_url
config = config_loader.call
# rubocop:disable Layout/LineLength
base_url + "/o/oauth2/v2/auth?client_id=#{config[:client_id]}&response_type=code&redirect_uri=#{URI.encode_www_form_component(config[:redirect_uri])}&scope=openid%20email%20profile"
# rubocop:enable Layout/LineLength
end

def create_identity(response, *)
Expand Down
9 changes: 1 addition & 8 deletions lib/code0/identities/provider/microsoft.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ module Code0
module Identities
module Provider
class Microsoft < BaseOauth
attr_reader :config_loader

def initialize(config_loader)
@config_loader = config_loader
end

def base_url
"https://graph.microsoft.com/"
end
Expand All @@ -24,8 +18,7 @@ def token_payload(code)
grant_type: "authorization_code",
redirect_uri: config[:redirect_uri],
client_id: config[:client_id],
client_secret: config[:client_secret]
}
client_secret: config[:client_secret] }
end

def user_details_url
Expand Down
24 changes: 24 additions & 0 deletions spec/code0/identities/identity_provider_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

RSpec.describe Code0::Identities::IdentityProvider do
let(:instance) do
described_class.new
end

describe "#add_provider" do
it "adds the correct class" do
instance.add_provider :google, -> {}
expect(instance.providers).to match(google: an_instance_of(Code0::Identities::Provider::Google))
end
end

describe "#load_identity" do
it "calls the right provider" do
provider = Code0::Identities::Provider::Google.new(-> {})
allow(provider).to receive(:load_identity)
instance.providers[:google] = provider
instance.load_identity(:google, { test: 1 })
expect(provider).to have_received(:load_identity).with({ test: 1 })
end
end
end
2 changes: 1 addition & 1 deletion spec/code0/identities/provider/discord_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
client_id: client_id,
client_secret: client_secret
}
}).load_identity(code)
}).load_identity(code: code)
end

let(:redirect_uri) { SecureRandom.hex }
Expand Down

0 comments on commit 0b96f20

Please sign in to comment.