1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# frozen_string_literal: true
module Scim
class Controller < ActionController::API
include ActionController::HttpAuthentication::Token::ControllerMethods
before_action :apply_scim_content_type
before_action :ensure_correct_content_type!
before_action :authenticate!
helper_method :current_user, :scim_type_for
rescue_from StandardError do |error|
Rails.logger.error(error)
render "server_error", status: :server_error
end
rescue_from ActiveRecord::RecordInvalid, with: :record_invalid
rescue_from ActiveModel::ValidationError, with: :record_invalid
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def current_user
Current.user
end
def current_user?
Current.user?
end
protected
def not_found
render json: {
schemas: [Scim::Kit::V2::Messages::ERROR],
detail: "Resource #{params[:id]} not found",
status: "404",
}.to_json, status: :not_found
end
def record_invalid(error)
@error = error
@model = error.respond_to?(:model) ? error.model : error.record
render "record_invalid", status: :bad_request
end
private
def authenticate!
Current.token = authenticate_with_http_token do |token|
Token.authenticate(token)
end
options = { status: :unauthorized, formats: :scim }
render "unauthorized", options unless Current.user?
end
def apply_scim_content_type
response.headers['Content-Type'] = Mime[:scim].to_s
end
def ensure_correct_content_type!
return if acceptable_content_type?
status = :unsupported_media_type
render 'unsupported_media_type', status: status, formats: :scim
end
def acceptable_content_type?
[:scim, :json].include?(request&.content_mime_type&.symbol)
end
def scim_type_for(error)
case error
when ActiveRecord::RecordInvalid
errors = error.record.errors.full_messages
if errors.count == 1 &&
errors[0].end_with?('has already been taken')
return 'uniqueness'
end
end
"invalidValue"
end
end
end
|