Class: SuperSettings::RackApplication

Inherits:
Object
  • Object
show all
Defined in:
lib/super_settings/rack_application.rb

Overview

Rack middleware for serving the REST API. See SuperSettings::RestAPI for more details on usage.

The routes for the API can be mounted under a common path prefix specified in the initializer.

You must specify some kind of authentication to use this class by at least overriding the authenticated? method in a subclass. How you do this is left up to you since you will most likely want to integrate in with how the rest of your application authenticates requests.

You are also responsible for implementing any CSRF protection if your authentication method uses stateful requests (i.e. cookies or Basic auth where browser automatically include the credentials on every request). There are other gems available that can be integrated into your middleware stack to provide this feature. If you need to inject meta elements into the page, you can do so with the add_to_head method.

Constant Summary collapse

RESPONSE_HEADERS =
{"content-type" => "application/json; charset=utf-8", "cache-control" => "no-cache"}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(app = nil, path_prefix = "/") { ... } ⇒ RackApplication

Returns a new instance of RackApplication.

Examples:


app = SuperSettings::RackApplication.new do
  def current_user(request)
    auth = request["HTTP_AUTHORIZATION"]
    token_match = auth&.match(/\ABearer:\s*(.*)/)
    token = token_match[1] if token_match
    User.identified_by(token)
  end

  def allow_write?(user)
    user.admin?
  end
end

Parameters:

  • app (Object) (defaults to: nil)

    Rack application or middleware for unhandled requests

  • path_prefix (String) (defaults to: "/")

    path prefix for the API routes.

Yields:

  • Block to be evaluated on the instance to extend it's behavior. You can use this to define the access control methods rather than having to extend the class.



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/super_settings/rack_application.rb', line 39

def initialize(app = nil, path_prefix = "/", &block)
  # Requiring rack here so that the gem does not have a hard dependency on it.
  begin
    require "rack"
  rescue LoadError
    raise LoadError, "SuperSettings::RackApplication requires the rack gem"
  end

  @app = app
  @path_prefix = path_prefix.to_s.chomp("/")
  instance_eval(&block) if block
end

Instance Method Details

#add_to_head(request) ⇒ String

Subclasses can override this method to add custom HTML to the element in the HTML application. This can be used to add additional script or meta tags needed for CSRF protection, etc.

Parameters:

  • request (Rack::Request)

    current reqeust object

Returns:

  • (String)


119
120
# File 'lib/super_settings/rack_application.rb', line 119

def add_to_head(request)
end

#allow_read?(user) ⇒ Boolean

Subclasses can override this method to indicate if the specified user is allowed to view settings. By default if a user is authenticated they will be able to read settings.

Parameters:

  • user (Object)

    the value returned by the current_user method.

Returns:

  • (Boolean)

    true if the user is can view settings.



85
86
87
# File 'lib/super_settings/rack_application.rb', line 85

def allow_read?(user)
  true
end

#allow_write?(user) ⇒ Boolean

Subclasses can override this method to indicate if the specified user is allowed to change settings. By default if a user can read settings, then they will be able to write them as well.

Parameters:

  • user (Object)

    the value returned by the current_user method.

Returns:

  • (Boolean)

    true if the user is can change settings.



94
95
96
# File 'lib/super_settings/rack_application.rb', line 94

def allow_write?(user)
  allow_read?(user)
end

#authenticated?(user) ⇒ Boolean

Subclasses can override this method to indicate if a user is authenticated. By default a request will be considered authenticated if the current_user method returns a value.

Parameters:

  • user (Object)

    the value returned by the current_user method.

Returns:

  • (Boolean)

    true if the user is authenticated.



76
77
78
# File 'lib/super_settings/rack_application.rb', line 76

def authenticated?(user)
  !!user
end

#call(env) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/super_settings/rack_application.rb', line 52

def call(env)
  if @path_prefix.empty? || "#{env["SCRIPT_NAME"]}#{env["PATH_INFO"]}".start_with?(@path_prefix)
    handle_request(env)
  elsif @app
    @app.call(env)
  else
    [404, {"content-type" => "text/plain"}, ["Not found"]]
  end
end

#changed_by(user) ⇒ String

Subclasses can override this method to return the information to record about the current user that will be stored in the setting history when a setting is changed.

Returns:

  • (String)


102
103
104
# File 'lib/super_settings/rack_application.rb', line 102

def changed_by(user)
  nil
end

#current_user(request) ⇒ Object

Subclasses must override this method to return the current user object. This object will be passed to the authenticated?, allow_read?, allow_write?, and changed_by methods.

Parameters:

  • request (Rack::Request)

    current request object

Returns:

  • (Object)

Raises:

  • (NotImplementedError)


67
68
69
# File 'lib/super_settings/rack_application.rb', line 67

def current_user(request)
  raise NotImplementedError
end

#layoutString, Symbol

Subclasses can override this method to return the path to an ERB file to use as the layout for the HTML application. The layout can use any of the methods defined in SuperSettings::Application::Helper.

Returns:

  • (String, Symbol)


110
111
112
# File 'lib/super_settings/rack_application.rb', line 110

def layout
  :default
end

#web_ui_enabled?Boolean

Subclasses can override this method to disable the web UI component of the application on only expose the REST API.

Returns:

  • (Boolean)


126
127
128
# File 'lib/super_settings/rack_application.rb', line 126

def web_ui_enabled?
  SuperSettings.configuration.controller.web_ui_enabled?
end