Commit 443ecda
Changed files (2)
app
controllers
spec
requests
app/controllers/oauths_controller.rb
@@ -21,24 +21,34 @@ class OauthsController < ApplicationController
def token
response.headers['Cache-Control'] = 'no-store'
response.headers['Pragma'] = 'no-cache'
- if token_params[:grant_type] == 'authorization_code'
- authorization = Authorization.active.find_by!(code: token_params[:code])
+
+ if params[:grant_type] == 'authorization_code'
+ authorization = Authorization.active.find_by!(code: params[:code])
@access_token, @refresh_token = authorization.exchange
- elsif token_params[:grant_type] == 'refresh_token'
- refresh_token = token_params[:refresh_token]
+ elsif params[:grant_type] == 'refresh_token'
+ refresh_token = params[:refresh_token]
jti = Token.claims_for(refresh_token, token_type: :refresh)[:jti]
@access_token, @refresh_token = Token.find_by!(uuid: jti).exchange
- elsif token_params[:grant_type] == 'client_credentials'
+ elsif params[:grant_type] == 'client_credentials'
@access_token = current_client.exchange
- elsif token_params[:grant_type] == 'password'
+ elsif params[:grant_type] == 'password'
user = User.login(params[:username], params[:password])
return render "bad_request", formats: :json, status: :bad_request unless user
@access_token, @refresh_token = user.issue_tokens_to(current_client)
+ elsif params[:grant_type] == 'urn:ietf:params:oauth:grant-type:saml2-bearer'
+ xml = Nokogiri::XML(Base64.urlsafe_decode64(params[:assertion]))
+ assertion = Saml::Kit::Assertion.new(xml)
+ if assertion.valid?
+ @access_token, @refresh_token = User.find_by!(uuid: assertion.name_id).issue_tokens_to(current_client)
+ else
+ return render "bad_request", formats: :json, status: :bad_request
+ end
else
return render "bad_request", formats: :json, status: :bad_request
end
render formats: :json
rescue StandardError => error
+ puts error.inspect
Rails.logger.error(error)
render "bad_request", formats: :json, status: :bad_request
end
@@ -47,10 +57,6 @@ class OauthsController < ApplicationController
attr_reader :current_client
- def token_params
- params.permit(:grant_type, :code, :refresh_token)
- end
-
def http_basic_authenticate!
@current_client = authenticate_with_http_basic do |client_id, client_secret|
Client.find_by(uuid: client_id)&.authenticate(client_secret)
spec/requests/oauth_spec.rb
@@ -174,5 +174,31 @@ RSpec.describe '/oauth' do
specify { expect(refresh_token.reload).to be_revoked }
end
end
+
+ context "when exchanging a SAML 2.0 assertion grant for tokens" do
+ context "when the assertion is valid" do
+ let(:user) { instance_double(User, name_id_for: SecureRandom.uuid, assertion_attributes_for: {}) }
+ let(:saml_request) { double(id: SecureRandom.uuid, issuer: Saml::Kit.configuration.entity_id) }
+
+ before :each do
+ saml = Saml::Kit::Response.build(user, saml_request)
+ post '/oauth/token', params: {
+ grant_type: 'urn:ietf:params:oauth:grant-type:saml2-bearer',
+ assertion: Base64.urlsafe_encode64(saml.assertion.to_xml),
+ }, headers: headers
+ end
+
+ specify { expect(response).to have_http_status(:ok) }
+ specify { expect(response.headers['Content-Type']).to include('application/json') }
+ specify { expect(response.headers['Cache-Control']).to include('no-store') }
+ specify { expect(response.headers['Pragma']).to eql('no-cache') }
+
+ let(:json) { JSON.parse(response.body, symbolize_names: true) }
+ specify { expect(json[:access_token]).to be_present }
+ specify { expect(json[:token_type]).to eql('Bearer') }
+ specify { expect(json[:expires_in]).to eql(1.hour.to_i) }
+ specify { expect(json[:refresh_token]).to be_present }
+ end
+ end
end
end