main
 1# frozen_string_literal: true
 2
 3module Oauth
 4  class ClientsController < ActionController::API
 5    include ActionController::HttpAuthentication::Token::ControllerMethods
 6    before_action :apply_cache_headers
 7    before_action :authenticate!, except: [:create]
 8
 9    def show
10      render status: :ok, formats: :json
11    end
12
13    def create
14      @client = Client.create!(transform(secure_params))
15      render status: :created, formats: :json
16    rescue ActiveRecord::RecordInvalid => error
17      json = {
18        error: error_type_for(error.record.errors),
19        error_description: error.record.errors.full_messages.join(' ')
20      }
21      render json: json, status: :bad_request
22    end
23
24    def update
25      @client = Client.find(params[:id])
26      @client.update!(transform(secure_params))
27      render status: :ok, formats: :json
28    rescue ActiveRecord::RecordInvalid => error
29      json = {
30        error: error_type_for(error.record.errors),
31        error_description: error.record.errors.full_messages.join(' ')
32      }
33      render json: json, status: :bad_request
34    end
35
36    private
37
38    def authenticate!
39      token = authenticate_with_http_token do |jwt, _options|
40        claims = Token.claims_for(jwt)
41        return if Token.revoked?(claims[:jti]) || claims.empty?
42
43        Token.find(claims[:jti])
44      end
45      return request_http_token_authentication if token.blank?
46
47      unless Client.where(id: params[:id]).exists?
48        token.revoke!
49        return render json: {}, status: :unauthorized
50      end
51      unless token.subject.to_param == params[:id]
52        return render json: {}, status: :forbidden
53      end
54
55      @client = token.subject
56    end
57
58    def secure_params
59      params.permit(
60        :client_name,
61        :token_endpoint_auth_method,
62        :logo_uri,
63        :jwks_uri,
64        redirect_uris: []
65      )
66    end
67
68    def transform(params)
69      {
70        name: params[:client_name],
71        redirect_uris: params[:redirect_uris],
72        token_endpoint_auth_method: params[:token_endpoint_auth_method],
73        logo_uri: params[:logo_uri],
74        jwks_uri: params[:jwks_uri],
75      }
76    end
77
78    def apply_cache_headers
79      response.headers["Cache-Control"] = "no-cache, no-store"
80      response.headers["Pragma"] = "no-cache"
81    end
82
83    def error_type_for(errors)
84      if errors[:redirect_uris].present?
85        :invalid_redirect_uri
86      else
87        :invalid_client_metadata
88      end
89    end
90  end
91end