Module: Shamu::Rails::Controller

Extended by:
ActiveSupport::Concern
Includes:
Scorpion::Rails::Controller
Defined in:
lib/shamu/rails/controller.rb

Overview

Adds convenience methods to a controller to access services and process entities in response to common requests. The mixin is automatically added to all controllers.

class UsersController < ApplicationController
  service :users_service, Users::UsersService
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.service(name, contract, **options, &block) ⇒ name

Define a service dependency on the controller. Each request will get its own instance of the service.

Parameters:

  • name (Symbol)

    of the attribute the service should be accessible through.

  • contract (Class)

    the class of the service that should be resolved at runtime.

  • options (Hash)

    additional dependency options. See Scorpion attr_dependency for details.

Options Hash (**options):

  • :lazy (Boolean)

    true if the service should be resolved the first time it's used instead of when the controller is initialized.

Returns:

  • (name)


127
128
129
130
131
# File 'lib/shamu/rails/controller.rb', line 127

def service( name, contract, **options, &block )
  services << name
  attr_dependency name, contract, options.merge( private: true )
  name
end

.servicesArray<Symbol>

Returns the list of service names on the controller.

Returns:

  • (Array<Symbol>)

    the list of service names on the controller.



108
109
110
111
112
# File 'lib/shamu/rails/controller.rb', line 108

def services
  @services ||= begin
    superclass.respond_to?( :services ) ? superclass.services.dup : []
  end
end

Instance Method Details

#permit?(action, resource, additional_context = nil) ⇒ :yes, ...

Checks if the requested behavior is permitted by any one of the #secure_services.

See Security::Policy#permit? for details.

Parameters:

  • action (Symbol)

    to perform.

  • resource (Object)

    the resource the action will be performed on.

  • additional_context (Object)

    that the policy may consider.

Returns:

  • (:yes, :maybe, false)

    a truthy value if permitted, otherwise false. The truthy value depends on the certainty of the policy. A value of :yes or true indicates the action is always permitted. A value of :maybe indicates the action is permitted but the user may need to present additional credentials such as logging on this session or entering a TFA code.



70
71
72
# File 'lib/shamu/rails/controller.rb', line 70

def permit?( *args )
  secure_services.any? { |s| s.permit?( *args ) }
end

#prepare_scorpion(scorpion) ⇒ Object

In included block so that it overrides Scorpion controller method.



27
28
29
30
31
32
33
34
35
# File 'lib/shamu/rails/controller.rb', line 27

def prepare_scorpion( scorpion )
  super

  scorpion.prepare do |s|
    s.hunt_for Shamu::Security::Principal do
      security_principal
    end
  end
end

#remote_ipString

Returns the IP address that the request originated from.

Returns:

  • (String)

    the IP address that the request originated from.



91
92
93
# File 'lib/shamu/rails/controller.rb', line 91

def remote_ip
  request.env["HTTP_X_REAL_IP"] || request.remote_ip
end

#secure_servicesArray<Services::Service>

Returns the list of services that can determine permissions for the controller.

Returns:

  • (Array<Services::Service>)

    the list of services that can determine permissions for the controller.



56
57
58
# File 'lib/shamu/rails/controller.rb', line 56

def secure_services
  @services ||= services.select { |s| s.respond_to?( :permit? ) }
end

#security_principalShamu::Security::Principal

Gets the security principal for the current request.



79
80
81
82
83
84
85
86
# File 'lib/shamu/rails/controller.rb', line 79

def security_principal
  @security_principal ||= begin
    Shamu::Security::Principal.new \
      user_id: current_user_id,
      remote_ip: remote_ip,
      elevated: session_elevated?
  end
end

#servicesArray<Services::Service>

Returns the list of services available to the controller.

Returns:



48
49
50
# File 'lib/shamu/rails/controller.rb', line 48

def services
  @services ||= self.class.services.map { |n| send n }
end

#session_elevated?Boolean

Override to indicate if the user has offerred their credentials this session rather than just using a 'remember me' style token

Returns:

  • (Boolean)

    true if the session has been elevated.



101
102
# File 'lib/shamu/rails/controller.rb', line 101

def session_elevated?
end