Class: Wurk::Web::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/wurk/web/config.rb

Overview

Web UI configuration. Holds the authorization callback documented in docs/target/sidekiq-ent.md §9.2 — a Rack-level hook called with ‘(env, method, path)` per request. Truthy return proceeds; falsey short-circuits to 403.

Wurk ships the Ent feature in the free gem. No license check; the block runs unconditionally when present.

Example:

Wurk::Web.configure do |c|
  c.authorization do |env, method, _path|
    user = env['warden']&.user
    method == 'GET' ? user&.support? || user&.admin? : user&.admin?
  end
end

When no block is registered, every request is authorized (matches Sidekiq’s default — no auth until the user opts in).

Constant Summary collapse

FALSEY_STRINGS =

String forms that mean “off” — so ‘config.web.read_only = ENV` doesn’t flip on when the env var is “0”/“false”/empty.

['', '0', 'false', 'no', 'off'].freeze

Instance Method Summary collapse

Constructor Details

#initializeConfig

Returns a new instance of Config.



37
38
39
40
41
42
# File 'lib/wurk/web/config.rb', line 37

def initialize
  @authorization = nil
  @read_only = env_read_only?
  @middlewares = []
  @rack_app = nil
end

Instance Method Details

#authorization(&block) ⇒ Object

Registers a ‘(env, method, path) -> truthy/falsey` block. Re-calling overwrites; the spec exposes a single hook, not a chain.



46
47
48
49
# File 'lib/wurk/web/config.rb', line 46

def authorization(&block)
  @authorization = block if block
  @authorization
end

#authorized?(env, method, path) ⇒ Boolean

Returns true when no block is registered, otherwise the block’s truthiness. The ‘path` argument is the engine-relative path so a consumer mounting under `/wurk` sees `/api/stats`, not the host’s absolute path — that matches Sidekiq’s contract.

Returns:

  • (Boolean)


99
100
101
102
103
# File 'lib/wurk/web/config.rb', line 99

def authorized?(env, method, path)
  return true if @authorization.nil?

  !!@authorization.call(env, method, path)
end

#middlewaresObject

Host-app Rack middleware stacked in front of the dashboard, newest last. Each entry is ‘[middleware, args, block]`. Returns a frozen copy so the memoized chain (`#rack_app`) can only be invalidated through `#use` — direct mutation can’t silently desync it.



33
34
35
# File 'lib/wurk/web/config.rb', line 33

def middlewares
  @middlewares.dup.freeze
end

#rack_app(inner) ⇒ Object

Builds (once) the host-middleware chain wrapping ‘inner` and memoizes it on this Config. `reset_config!` swaps in a fresh Config, so each test rebuilds cleanly; production builds exactly once at boot.



65
66
67
68
69
70
71
72
73
# File 'lib/wurk/web/config.rb', line 65

def rack_app(inner)
  @rack_app ||= begin
    stack = @middlewares
    ::Rack::Builder.new do
      stack.each { |middleware, args, block| use(middleware, *args, &block) }
      run inner
    end.to_app
  end
end

#read_only=(value) ⇒ Object

Read-only mode. When on, the Authorization middleware blocks every non-GET request (retry/kill/requeue/delete/pause/resume/clear) with 403, and the SPA hides destructive actions via the /api/meta flag. Defaults from WURK_WEB_READ_ONLY=1 so a viewer-only deploy (e.g. the public demo) needs no Ruby config.



80
81
82
# File 'lib/wurk/web/config.rb', line 80

def read_only=(value)
  @read_only = value.is_a?(String) ? !FALSEY_STRINGS.include?(value.strip.downcase) : !!value
end

#read_only?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/wurk/web/config.rb', line 84

def read_only?
  @read_only
end

#reset!Object



88
89
90
91
92
93
# File 'lib/wurk/web/config.rb', line 88

def reset!
  @authorization = nil
  @read_only = env_read_only?
  @middlewares = []
  @rack_app = nil
end

#use(middleware, *args, &block) ⇒ Object

Sidekiq-compatible (‘Sidekiq::Web.use`). Registers a Rack middleware that wraps the dashboard, in front of the authorization hook, so a host app can gate the UI with Devise/Warden/Sorcery/Rack::Auth::Basic without writing its own middleware. `args` and an optional block pass straight through to the middleware’s ‘new`. Call before the first request (i.e. from an initializer) — the chain is built once.



57
58
59
60
# File 'lib/wurk/web/config.rb', line 57

def use(middleware, *args, &block)
  @middlewares << [middleware, args, block]
  @rack_app = nil
end