Class: Scimitar::ResourcesController

Inherits:
ApplicationController show all
Defined in:
app/controllers/scimitar/resources_controller.rb

Overview

A Rails controller which is mostly idiomatic, with #index, #show, #create and #destroy methods mapping to the conventional HTTP methods in Rails. The #update method is used for partial-update PATCH calls, while the #replace method is used for whole-update PUT calls.

Subclass this controller to deal with resource-specific API calls, for endpoints such as Users and Groups. Any one controller is assumed to be related to one class in your application which has mixed in Scimitar::Resources::Mixin. Your subclass MUST override protected method #storage_class, which returns that class. For example, if you had a class User with the mixin included, then:

protected
  def storage_class
    User
  end

…is sufficient.

The controller makes no assumptions about storage method - it does not have any ActiveRecord specialisations, for example. If you do use ActiveRecord, consider subclassing Scimitar::ActiveRecordBackedResourcesController instead as it does most of the mapping, persistence and error handling work for you.

Direct Known Subclasses

ActiveRecordBackedResourcesController

Instance Method Summary collapse

Instance Method Details

#create(&block) ⇒ Object

POST (create)

Call with a block that is passed a SCIM resource instance - e.g a Scimitar::Resources::User instance - representing an item to be created. Your ::storage_class class’s ::scim_resource_type method determines the kind of object you’ll be given.

See also e.g. Scimitar::Resources::Mixin#from_scim!.

Evaluate to the SCIM representation of the arising created record.



77
78
79
80
81
# File 'app/controllers/scimitar/resources_controller.rb', line 77

def create(&block)
  with_scim_resource() do |resource|
    render(json: yield(resource, :create), status: :created)
  end
end

#destroyObject

DELETE (remove)



119
120
121
122
123
124
125
126
127
128
# File 'app/controllers/scimitar/resources_controller.rb', line 119

def destroy
  if yield(self.safe_params()[:id]) != false
    head :no_content
  else
    raise ErrorResponse.new(
      status: 500,
      detail: "Failed to delete the resource with id '#{params[:id]}'. Please try again later."
    )
  end
end

#index(pagination_info, page_of_results, &block) ⇒ Object

GET (list)

Pass a Scimitar::Lists::Count object providing pagination data along with a page of results in “your” data domain as an Enumerable, along with a block. Renders as “list” result by calling your block with each of the results, allowing you to use something like Scimitar::Resources::Mixin#to_scim to convert to a SCIM representation.

pagination_info

A Scimitar::Lists::Count instance with #total set. See e.g. protected method #scim_pagination_info to assist with this.

page_of_results

An Enumerable single page of results.



44
45
46
47
48
49
50
51
52
53
54
# File 'app/controllers/scimitar/resources_controller.rb', line 44

def index(pagination_info, page_of_results, &block)
  render(json: {
    schemas: [
        'urn:ietf:params:scim:api:messages:2.0:ListResponse'
    ],
    totalResults: pagination_info.total,
    startIndex:   pagination_info.start_index,
    itemsPerPage: pagination_info.limit,
    Resources:    page_of_results.map(&block)
  })
end

#replace(&block) ⇒ Object

PUT (replace)

Similar to #create, but you’re passed an ID to find as well as the resource details to then use for all replacement attributes in that found resource. See also e.g. Scimitar::Resources::Mixin#from_scim!.

Evaluate to the SCIM representation of the arising created record.



91
92
93
94
95
# File 'app/controllers/scimitar/resources_controller.rb', line 91

def replace(&block)
  with_scim_resource() do |resource|
    render(json: yield(self.safe_params()[:id], resource))
  end
end

#show(&block) ⇒ Object

GET/id (show)

Call with a block that is passed an ID to find in “your” domain. Evaluate to the SCIM representation of the arising found record.



61
62
63
64
# File 'app/controllers/scimitar/resources_controller.rb', line 61

def show(&block)
  scim_resource = yield(self.safe_params()[:id])
  render(json: scim_resource)
end

#update(&block) ⇒ Object

PATCH (update)

A variant of #create where you’re again passed the resource ID (in “your” domain) to look up, but then a Hash with patch operation details from the calling client. This can be passed to e.g. Scimitar::Resources::Mixin#from_scim_patch!.

Evaluate to the SCIM representation of the arising created record.



106
107
108
109
110
111
112
113
114
115
# File 'app/controllers/scimitar/resources_controller.rb', line 106

def update(&block)
  validate_request()

  # Params includes all of the PATCH data at the top level along with other
  # other Rails-injected params like 'id', 'action', 'controller'. These
  # are harmless given no namespace collision and we're only interested in
  # the 'Operations' key for the actual patch data.
  #
  render(json: yield(self.safe_params()[:id], self.safe_params().to_hash()))
end