Commit ca66b19

mo <mo.khan@gmail.com>
2018-09-04 22:56:09
add resource types.
1 parent 056605e
Changed files (8)
app/controllers/scim/v2/resource_types_controller.rb
@@ -2,7 +2,20 @@
 
 module Scim
   module V2
-    class ResourceTypesController < ApplicationController
+    class ResourceTypesController < ::Scim::Controller
+      def index
+        render status: :ok
+      end
+
+      def show
+        if params[:id] == 'User'
+          render partial: 'user', formats: :scim, status: :ok
+        elsif params[:id] == 'Group'
+          render partial: 'group', formats: :scim, status: :ok
+        else
+          raise ActiveRecord::RecordNotFound
+        end
+      end
     end
   end
 end
app/models/scim/schema.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module SCIM
+  module Schema
+    ERROR = 'urn:ietf:params:scim:api:messages:2.0:Error'
+    GROUP = 'urn:ietf:params:scim:schemas:core:2.0:Group'
+    RESOURCE_TYPE = 'urn:ietf:params:scim:schemas:core:2.0:ResourceType'
+    USER = 'urn:ietf:params:scim:schemas:core:2.0:User'
+  end
+end
app/views/scim/v2/resource_types/_group.scim.jbuilder
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+json.schemas [SCIM::Schema::RESOURCE_TYPE]
+json.id "Group"
+json.meta do
+  json.location scim_v2_resource_type_url(id: 'Group')
+  json.resourceType "ResourceType"
+end
+json.description "Group"
+json.endpoint scim_v2_groups_url
+json.name "Group"
+json.schema SCIM::Schema::GROUP
+json.schemaExtensions []
app/views/scim/v2/resource_types/_user.scim.jbuilder
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+json.schemas [SCIM::Schema::RESOURCE_TYPE]
+json.id "User"
+json.meta do
+  json.location scim_v2_resource_type_url(id: 'User')
+  json.resourceType "ResourceType"
+end
+json.description "User Account"
+json.endpoint scim_v2_users_url
+json.name "User"
+json.schema SCIM::Schema::USER
+json.schemaExtensions []
app/views/scim/v2/resource_types/index.scim.jbuilder
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+json.array! [
+  {
+    "schemas": [SCIM::Schema::RESOURCE_TYPE],
+    "id": "User",
+    "meta": {
+      "location": scim_v2_resource_type_url(id: 'User'),
+      "resourceType": "ResourceType"
+    },
+    "description": "User Account",
+    "endpoint": scim_v2_users_url,
+    "name": "User",
+    "schema": SCIM::Schema::USER,
+    "schemaExtensions": []
+  },
+  {
+    "schemas": [SCIM::Schema::RESOURCE_TYPE],
+    "id": "Group",
+    "meta": {
+      "location": scim_v2_resource_type_url(id: 'Group'),
+      "resourceType": "ResourceType"
+    },
+    "description": "Group",
+    "endpoint": scim_v2_groups_url,
+    "name": "Group",
+    "schema": SCIM::Schema::GROUP,
+    "schemaExtensions": []
+  }
+]
config/initializers/mime_types.rb
@@ -6,7 +6,6 @@
 # Mime::Type.register "text/richtext", :rtf
 Mime::Type.register "application/scim+json", :scim
 
-scim_parser = ActionDispatch::Request.parameter_parsers[:json]
-original_parsers = ActionDispatch::Request.parameter_parsers
-ActionDispatch::Request.parameter_parsers =
-  original_parsers.merge(Mime[:scim].symbol => scim_parser)
+ActionDispatch::Request.parameter_parsers[:scim] = lambda do |body|
+  JSON.parse(body)
+end
config/routes.rb
@@ -15,12 +15,26 @@ Rails.application.routes.draw do
   namespace :scim do
     namespace :v2, defaults: { format: :scim } do
       post ".search", to: "search#index"
-      resources :users, only: [:index, :show, :create, :update, :destroy]
-      get :ServiceProviderConfig, to: "service_providers#show"
+
+      get 'Groups/:id', to: 'groups#show'
+      post :Groups, to: "groups#create"
+      put 'Groups/:id', to: "groups#update"
       resources :groups, only: [:index]
-      resources :resource_types, only: [:index]
+
       get :ResourceTypes, to: "resource_types#index"
-      resources :schemas, only: [:index]
+      get 'ResourceTypes/:id', to: "resource_types#show"
+      resources :resource_types, only: [:index, :show]
+
+      get :Schemas, to: 'schemas#index'
+      get 'Schemas/:id', to: "schemas#show"
+      resources :schemas, only: [:index, :show]
+
+      get :ServiceProviderConfig, to: "service_providers#show"
+
+      get 'Users/:id', to: 'users#show'
+      post :Users, to: "users#create"
+      put 'Users/:id', to: "users#update"
+      resources :users, only: [:index, :show, :create, :update, :destroy]
 
       match 'Me', to: lambda { |env| [501, {}, ['']] }, via: [:get, :post, :put, :patch, :delete]
       match 'Bulk', to: lambda { |env| [501, {}, ['']] }, via: [:post]
spec/requests/scim/v2/resource_types_spec.rb
@@ -0,0 +1,70 @@
+require 'rails_helper'
+
+RSpec.describe "/scim/v2/ResourceTypes" do
+  let(:user) { create(:user) }
+  let(:token) { user.access_token('audience') }
+  let(:headers) do
+    {
+      'Accept' => 'application/scim+json',
+      'Content-Type' => 'application/scim+json',
+      'Authorization' => "Bearer #{token}"
+    }
+  end
+
+  describe "GET /scim/v2/ResourceTypes" do
+    before { get "/scim/v2/ResourceTypes", headers: headers }
+    let(:json) { JSON.parse(response.body, symbolize_names: true) }
+
+    specify { expect(response).to have_http_status(:ok) }
+    specify { expect(json.count).to eql(2) }
+    specify { expect(json[0][:schemas]).to match_array(["urn:ietf:params:scim:schemas:core:2.0:ResourceType"]) }
+    specify { expect(json[0][:id]).to eql('User') }
+    specify { expect(json[0][:name]).to eql('User') }
+    specify { expect(json[0][:endpoint]).to eql(scim_v2_users_url) }
+    specify { expect(json[0][:meta][:location]).to eql(scim_v2_resource_type_url(id: 'User')) }
+    specify { expect(json[0][:meta][:resourceType]).to eql('ResourceType') }
+
+    specify { expect(json[1][:schemas]).to match_array(["urn:ietf:params:scim:schemas:core:2.0:ResourceType"]) }
+    specify { expect(json[1][:id]).to eql('Group') }
+    specify { expect(json[1][:name]).to eql('Group') }
+    specify { expect(json[1][:schema]).to eql('urn:ietf:params:scim:schemas:core:2.0:Group') }
+    specify { expect(json[1][:endpoint]).to eql(scim_v2_groups_url) }
+    specify { expect(json[1][:meta][:location]).to eql(scim_v2_resource_type_url(id: 'Group')) }
+    specify { expect(json[1][:meta][:resourceType]).to eql('ResourceType') }
+    specify { expect(json[1][:schemaExtensions]).to match_array([]) }
+  end
+
+  describe "GET /scim/v2/ResourceTypes/User" do
+    before { get "/scim/v2/ResourceTypes/User", headers: headers }
+    let(:json) { JSON.parse(response.body, symbolize_names: true) }
+
+    specify { expect(response).to have_http_status(:ok) }
+    specify { expect(json[:schemas]).to match_array(["urn:ietf:params:scim:schemas:core:2.0:ResourceType"]) }
+    specify { expect(json[:id]).to eql('User') }
+    specify { expect(json[:name]).to eql('User') }
+    specify { expect(json[:endpoint]).to eql(scim_v2_users_url) }
+    specify { expect(json[:meta][:location]).to eql(scim_v2_resource_type_url(id: 'User')) }
+    specify { expect(json[:meta][:resourceType]).to eql('ResourceType') }
+  end
+
+  describe "GET /scim/v2/ResourceTypes/Group" do
+    before { get "/scim/v2/ResourceTypes/Group", headers: headers }
+    let(:json) { JSON.parse(response.body, symbolize_names: true) }
+
+    specify { expect(response).to have_http_status(:ok) }
+    specify { expect(json[:schemas]).to match_array(["urn:ietf:params:scim:schemas:core:2.0:ResourceType"]) }
+    specify { expect(json[:id]).to eql('Group') }
+    specify { expect(json[:name]).to eql('Group') }
+    specify { expect(json[:endpoint]).to eql(scim_v2_groups_url) }
+    specify { expect(json[:meta][:location]).to eql(scim_v2_resource_type_url(id: 'Group')) }
+    specify { expect(json[:meta][:resourceType]).to eql('ResourceType') }
+    specify { expect(json[:schema]).to eql('urn:ietf:params:scim:schemas:core:2.0:Group') }
+    specify { expect(json[:schemaExtensions]).to match_array([]) }
+  end
+
+  describe "GET /scim/v2/ResourceTypes/unknown" do
+    before { get "/scim/v2/ResourceTypes/unknown", headers: headers }
+
+    specify { expect(response).to have_http_status(:not_found) }
+  end
+end