# frozen_string_literal: true module Api module OpenidConnect module AuthorizationPoint class Endpoint attr_accessor :app, :user, :o_auth_application, :redirect_uri, :response_type, :scopes, :request_uri, :request_object, :nonce delegate :call, to: :app def initialize(user) @user = user @app = Rack::OAuth2::Server::Authorize.new do |req, res| build_from_request_object(req) build_attributes(req, res) if OAuthApplication.available_response_types.include? Array(req.response_type).join(" ") handle_response_type(req, res) else req.unsupported_response_type! end end end def build_attributes(req, res) build_client(req) build_redirect_uri(req, res) verify_nonce(req, res) build_scopes(req) end def handle_response_type(_req, _res) raise NotImplementedError # Implemented by subclass end private def build_client(req) @o_auth_application = OAuthApplication.find_by_client_id(req.client_id) || req.bad_request! end def build_redirect_uri(req, res) res.redirect_uri = @redirect_uri = req.verify_redirect_uri!(@o_auth_application.redirect_uris) end def verify_nonce(req, res) req.invalid_request! "nonce required" if res.protocol_params_location == :fragment && req.nonce.blank? end def build_scopes(req) @scopes = req.scope.map {|scope| scope.tap do |scope_name| req.invalid_scope! I18n.t("api.openid_connect.authorizations.new.unknown_scope", scope_name: scope_name) \ unless auth_scopes.include?(scope_name) end } @scopes.push("public:read") unless @scopes.include?("public:read") has_private_scope = @scopes.include?("private:read") || @scopes.include?("private:modify") has_contacts_scope = @scopes.include? "contacts:read" req.invalid_scope! I18n.t("api.openid_connect.authorizations.new.private_contacts_linkage_error") \ if has_private_scope && !has_contacts_scope end def auth_scopes Api::OpenidConnect::Authorization::SCOPES end end end end end