Class: TwoPercent::ScimController

Inherits:
ApplicationController show all
Defined in:
app/controllers/two_percent/scim_controller.rb

Instance Method Summary collapse

Methods inherited from ApplicationController

#authenticate

Instance Method Details

#createObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'app/controllers/two_percent/scim_controller.rb', line 5

def create
  record = with_scim_logging("create") do
    # Persist to two_percent tables first (validates SCIM schema)
    record = persist_scim_record(scim_params)

    # Reload with associations for domain event and response
    record = reload_with_members(record)

    # Publish domain event (not SCIM-specific)
    publish_created_event(record)

    record
  end

  # RFC 7644: 201 Created with Location header and resource body
  render json: record.to_scim_representation, status: :created, location: scim_resource_url(record)
end

#destroyObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'app/controllers/two_percent/scim_controller.rb', line 78

def destroy
  scim_id = with_scim_logging("delete") do
    # Find and destroy record
    record = find_scim_record(params[:id])
    scim_id = record.scim_id

    # Destroy record
    model_class.destroy_by_scim_id(scim_id)

    # Publish domain delete event
    publish_deleted_event(scim_id)

    scim_id
  end

  # RFC 7644: 204 No Content
  head :no_content
end

#indexObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'app/controllers/two_percent/scim_controller.rb', line 112

def index
  validate_resource_type!
  log_scim_operation("list", "start")

  # Build base query scope
  scope = build_query_scope

  # Get total count before pagination
  total_count = scope.count

  # Apply pagination
  paginated_scope = apply_pagination(scope)

  # Load records with associations
  records = load_records_with_associations(paginated_scope)

  # Build RFC 7644 ListResponse
  list_response = build_list_response(records, total_count)

  log_scim_operation("list", "complete")

  # RFC 7644: 200 OK with ListResponse (no domain events for read operations)
  render json: list_response, status: :ok
end

#replaceObject



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
# File 'app/controllers/two_percent/scim_controller.rb', line 50

def replace
  # Upsert record (create or replace)
  was_new = !model_class.exists_by_scim_id?(params[:id])

  record = with_scim_logging("replace") do
    record = upsert_scim_record(params[:id], scim_params)

    # Reload with associations for domain event and response
    record = reload_with_members(record)

    # Publish appropriate domain event
    if was_new
      publish_created_event(record)
    else
      publish_updated_event(record)
    end

    record
  end

  # RFC 7644: 201 Created (if new) or 200 OK (if replaced)
  if was_new
    render json: record.to_scim_representation, status: :created, location: scim_resource_url(record)
  else
    render json: record.to_scim_representation, status: :ok
  end
end

#showObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/controllers/two_percent/scim_controller.rb', line 97

def show
  validate_resource_type!

  record = with_scim_logging("get") do
    # Find record (raises RecordNotFound if not exists)
    record = find_scim_record(params[:id])

    # Reload with associations for complete SCIM representation
    reload_with_members(record)
  end

  # RFC 7644: 200 OK with resource body (no domain events for read operations)
  render json: record.to_scim_representation, status: :ok
end

#updateObject



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
# File 'app/controllers/two_percent/scim_controller.rb', line 23

def update
  record = with_scim_logging("update") do
    # Find existing record
    record = find_scim_record(params[:id])

    # Apply SCIM PATCH operations (RFC 7644 compliance)
    processor = TwoPercent::Scim::PatchProcessor.new(scim_params)
    current_scim_data = record.scim_data || {}
    patched_data = processor.apply_to_hash(current_scim_data)

    # Persist patched data
    patched_data["id"] = params[:id] # Ensure ID is present
    updated_record = persist_scim_record(patched_data)

    # Reload with associations for domain event and response
    updated_record = reload_with_members(updated_record)

    # Publish domain event with final state
    publish_updated_event(updated_record)

    updated_record
  end

  # RFC 7644: 200 OK with updated resource body
  render json: record.to_scim_representation, status: :ok
end