ActionController::Base
Application
Controller
ImportsController
class User < Struct.new(:token, :admin?)
def self.find_by_token(token)
case token
when /admin/ then self.new(token, true)
when /user/ then self.new(token, false)
else nil
end
end
end
class User < Struct.new(:token, :admin?)
end
class User < Struct.new(:token, :admin?)
end
class User < Struct.new(:token, :admin?)
def self.find_by_token(token)
case token
when /admin/ then self.new(token, true)
when /user/ then self.new(token, false)
else nil
end
end
def self.find_by_token!(token)
find_by_token(token) or
raise(
ActiveRecord::RecordNotFound,
"user '#{token}' not found")
end
end
>>
>> User.find_by_token("user_1")
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>>
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>>
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>>
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>> User.find_by_token!("invalid")
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>> User.find_by_token!("invalid")
#> ActiveRecord::RecordNotFound: user 'invalid' not found
>>
class User < Struct.new(:token, :admin?)
def self.find_by_token(token)
case token
when /admin/ then self.new(token, true)
when /user/ then self.new(token, false)
else nil
end
end
def self.find_by_token!(token)
find_by_token(token) or
raise(
ActiveRecord::RecordNotFound,
"user '#{token}' not found")
end
end
AC = ActionController
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>> User.find_by_token!("invalid")
#> ActiveRecord::RecordNotFound: user 'invalid' not found
>> AC
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>> User.find_by_token!("invalid")
#> ActiveRecord::RecordNotFound: user 'invalid' not found
>> AC
=> ActionController
>>
class User < Struct.new(:token, :admin?)
def self.find_by_token(token)
case token
when /admin/ then self.new(token, true)
when /user/ then self.new(token, false)
else nil
end
end
def self.find_by_token!(token)
find_by_token(token) or
raise(
ActiveRecord::RecordNotFound,
"user '#{token}' not found")
end
end
AC = ActionController
AR = ActiveRecord
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>> User.find_by_token!("invalid")
#> ActiveRecord::RecordNotFound: user 'invalid' not found
>> AC
=> ActionController
>> AR
>> User.find_by_token("user_1")
=> #<User token="user_1", admin?=false>
>> User.find_by_token("admin_1")
=> #<User token="admin_1", admin?=true>
>> User.find_by_token("invalid")
=> nil
>> User.find_by_token!("invalid")
#> ActiveRecord::RecordNotFound: user 'invalid' not found
>> AC
=> ActionController
>> AR
=> ActiveRecord
>>
class User < Struct.new(:token, :admin?)
def self.find_by_token(token)
case token
when /admin/ then self.new(token, true)
when /user/ then self.new(token, false)
else nil
end
end
def self.find_by_token!(token)
find_by_token(token) or
raise(
AR::RecordNotFound,
"user '#{token}' not found")
end
end
AC = ActionController
AR = ActiveRecord
class User < Struct.new(:token, :admin?)
# ...
end
class Widget
end
>>
class User < Struct.new(:token, :admin?)
# ...
end
class Widget
end
class User < Struct.new(:token, :admin?)
# ...
end
class Widget
def self.all
{ widgets: "all" }
end
end
class User < Struct.new(:token, :admin?)
# ...
end
class Widget
def self.all
{ widgets: "all" }
end
def self.for(user)
{ widgets: "for #{user.token}" }
end
end
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>>
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>> Widget.for(user)
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>> Widget.for(user)
=> { widgets: "for user_1" }
>>
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>> Widget.for(user)
=> { widgets: "for user_1" }
>> Widget.for(admin)
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>> Widget.for(user)
=> { widgets: "for user_1" }
>> Widget.for(admin)
=> { widgets: "for admin_1" }
>>
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>> Widget.for(user)
=> { widgets: "for user_1" }
>> Widget.for(admin)
=> { widgets: "for admin_1" }
>> Widget.all
>> user = User.find_by_token("user_1")
=> #<User token="user_1", :admin?=false>
>> admin = User.find_by_token("admin_1")
=> #<User token="admin_1", :admin?=true>
>> Widget.for(user)
=> { widgets: "for user_1" }
>> Widget.for(admin)
=> { widgets: "for admin_1" }
>> Widget.all
=> { widgets: "all" }
>>
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
end
module Asserting
extend ActiveSupport::Concern
included do |base|
base.rescue_from(StandardError) do |error|
if error.is_a?(AssertionError)
self.render_error(error.message)
else
raise error
end
end
end
def assert(value, status)
value or raise AssertionError, status
end
AssertionError = Class.new(StandardError)
end
module Asserting
extend ActiveSupport::Concern
included do |base|
base.rescue_from(StandardError) do |error|
if error.is_a?(AssertionError)
self.render_error(error.message)
else
raise error
end
end
end
def assert(value, status)
value or raise AssertionError, status
end
AssertionError = Class.new(StandardError)
end
module Rendering
def render_error(error_message)
render text: "ERROR: #{error_message}"
end
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
# ...
end
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
# ...
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
# ...
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
if current_user.admin?
render json: Widget.all
else
render json: Widget.for(current_user)
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
end
$
$ curl localhost:3000/widgets
$ curl localhost:3000/widgets
{"error":"no token"}
$
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$ curl localhost:3000/widgets?token=user_2
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$ curl localhost:3000/widgets?token=user_2
{"widgets":"for user_2"}
$
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$ curl localhost:3000/widgets?token=user_2
{"widgets":"for user_2"}
$ curl localhost:3000/widgets?token=admin_1
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$ curl localhost:3000/widgets?token=user_2
{"widgets":"for user_2"}
$ curl localhost:3000/widgets?token=admin_1
{"widgets":"all"}
$
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$ curl localhost:3000/widgets?token=user_2
{"widgets":"for user_2"}
$ curl localhost:3000/widgets?token=admin_1
{"widgets":"all"}
$ curl localhost:3000/widgets?token=admin_2
$ curl localhost:3000/widgets
{"error":"no token"}
$ curl localhost:3000/widgets?token=foo
{"error":"user 'foo' not found"}
$ curl localhost:3000/widgets?token=user_1
{"widgets":"for user_1"}
$ curl localhost:3000/widgets?token=user_2
{"widgets":"for user_2"}
$ curl localhost:3000/widgets?token=admin_1
{"widgets":"all"}
$ curl localhost:3000/widgets?token=admin_2
{"widgets":"all"}
$
class WidgetsController < AppController
before_action :set_current_user
def index
if current_user.admin?
render json: Widget.all
else
render json: Widget.for(current_user)
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
end
$
class AppController < AC::Base
# ...
end
class AppController < AC::Base
# ...
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
# ...
attr_reader :true_user
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
widgets = if current_user.admin?
Widget.all
else
Widget.for(current_user)
end
render json: widgets
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
widgets = if current_user.admin?
Widget.all
else
Widget.for(current_user)
end
render json: widgets.merge(
as: true_user.token
)
end
end
class WidgetsController < AppController
before_action :set_current_user
def index
widgets = if current_user.admin?
Widget.all
else
Widget.for(current_user)
end
render json: widgets.merge(
as: true_user&.token
)
end
end
$ curl 'localhost:3000/widgets?token=user_1'
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_2'
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_2'
{"widgets":"for user_2","as":"admin_1"}
$
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_2'
{"widgets":"for user_2","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=user_1&ghost=admin_1'
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_2'
{"widgets":"for user_2","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=user_1&ghost=admin_1'
{"widgets":"for user_1","as":null}
$
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_2'
{"widgets":"for user_2","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=user_1&ghost=admin_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=admin_2'
$ curl 'localhost:3000/widgets?token=user_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1'
{"widgets":"all","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=user_2'
{"widgets":"for user_2","as":"admin_1"}
$ curl 'localhost:3000/widgets?token=user_1&ghost=admin_1'
{"widgets":"for user_1","as":null}
$ curl 'localhost:3000/widgets?token=admin_1&ghost=admin_2'
{"widgets":"all","as":"admin_1"}
$
class WidgetsController < AppController
before_action :set_current_user
before_action :allow_ghosting
def index
widgets = if current_user.admin?
Widget.all
else
Widget.for(current_user)
end
render json: widgets.merge(
as: true_user&.token
)
end
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user, :true_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
module Rendering
def render_error(error_message)
render json: { error: error_message }
end
end
class WidgetsController < AppController
before_action :set_current_user
before_action :allow_ghosting
def index
widgets = if current_user.admin?
Widget.all
else
Widget.for(current_user)
end
render json: widgets
.merge(as: true_user&.token)
end
end
module Asserting
extend ActiveSupport::Concern
included do |base|
base.rescue_from(StandardError) do |error|
if error.is_a?(AssertionError)
self.render_error(error.message)
else
raise error
end
end
end
def assert(value, status)
value or raise AssertionError, status
end
AssertionError = Class.new(StandardError)
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user, :true_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
module Rendering
def render_error(error_message)
render json: { error: error_message }
end
end
module Asserting
extend ActiveSupport::Concern
included do |base|
base.rescue_from(StandardError) do |error|
if error.is_a?(AssertionError)
self.render_error(error.message)
else
raise error
end
end
end
def assert(value, status)
value or raise AssertionError, status
end
AssertionError = Class.new(StandardError)
end
class AppController < AC::Base
include Rendering
include Asserting
private
attr_reader :current_user, :true_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params[:token]
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
assert(token, "no token")
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
assert(user, "user '#{token}' not found")
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
assert(ghost_target,
"user '#{ghost_token}' not found")
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
include Asserting
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
include Rendering
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
Rails.application.routes.draw do
resources :widgets, only: :index
end
module UserApi
class WidgetsController < AppController
end
end
Rails.application.routes.draw do
resources :widgets, only: :index
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
end
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
end
end
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
resources :widgets, only: :index
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(current_user)
end
end
end
$
$ curl 'localhost:3000/user_api/user_1/widgets'
$ curl 'localhost:3000/user_api/user_1/widgets'
{"error":"param is missing or the value is empty: token"}
$
$ curl 'localhost:3000/user_api/user_1/widgets'
{"error":"param is missing or the value is empty: token"}
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
$ curl 'localhost:3000/user_api/user_1/widgets'
{"error":"param is missing or the value is empty: token"}
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1"}
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_2'
$ curl 'localhost:3000/user_api/user_1/widgets'
{"error":"param is missing or the value is empty: token"}
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1"}
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_2'
{"widgets":"for user_2"}
$
$ curl 'localhost:3000/user_api/user_1/widgets'
{"error":"param is missing or the value is empty: token"}
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1"}
$
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
resources :widgets, only: :index
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(current_user)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(current_user)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(current_user)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(resource_user)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user
render json: { error: "Forbidden" }
end
end
end
end
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1","as":"user_1"}
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1","as":"user_1"}
$ curl 'localhost:3000/user_api/user_2/widgets?token=user_2'
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1","as":"user_1"}
$ curl 'localhost:3000/user_api/user_2/widgets?token=user_2'
{"widgets":"for user_2","as":"user_2"}
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1","as":"user_1"}
$ curl 'localhost:3000/user_api/user_2/widgets?token=user_2'
{"widgets":"for user_2","as":"user_2"}
$ curl 'localhost:3000/user_api/user_2/widgets?token=user_1'
$ curl 'localhost:3000/user_api/user_1/widgets?token=user_1'
{"widgets":"for user_1","as":"user_1"}
$ curl 'localhost:3000/user_api/user_2/widgets?token=user_2'
{"widgets":"for user_2","as":"user_2"}
$ curl 'localhost:3000/user_api/user_2/widgets?token=user_1'
{"error":"Forbidden"}
$
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
resources :widgets, only: :index
end
end
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
resources :widgets, only: :index
end
end
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
resources :widgets, only: :index
end
end
# /admin_api/widgets
end
Rails.application.routes.draw do
resources :widgets, only: :index
# /user_api/:user_id/widgets
namespace :user_api do
scope path: ':user_id' do
resources :widgets, only: :index
end
end
# /admin_api/widgets
namespace :admin_api do
resources :widgets, only: :index
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
def index
render json: Widget.all
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
end
private
def auth_admin
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
end
private
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
$
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=admin_2'
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=admin_2'
{"widgets":"all","as":"admin_2"}
$
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=admin_2'
{"widgets":"all","as":"admin_2"}
$ curl 'localhost:3000/admin_api/widgets?token=user_1'
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=admin_2'
{"widgets":"all","as":"admin_2"}
$ curl 'localhost:3000/admin_api/widgets?token=user_1'
{"error":"Forbidden"}
$
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user
render json: { error: "Forbidden" }
end
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=admin_1'
$ curl 'localhost:3000/user_api/user_1/widgets?token=admin_1'
{"widgets":"for user_1","as":"admin_1"}
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=admin_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/user_api/admin_1/widgets?token=admin_1'
{"widgets":"for admin_1","as":"admin_1"}
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=admin_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/user_api/admin_1/widgets?token=admin_1'
{"widgets":"for admin_1","as":"admin_1"}
$ curl 'localhost:3000/user_api/admin_2/widgets?token=admin_1'
$ curl 'localhost:3000/user_api/user_1/widgets?token=admin_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/user_api/admin_1/widgets?token=admin_1'
{"widgets":"for admin_1","as":"admin_1"}
$ curl 'localhost:3000/user_api/admin_2/widgets?token=admin_1'
{"widgets":"for admin_2","as":"admin_1"}
$
$ curl 'localhost:3000/user_api/user_1/widgets?token=admin_1'
{"widgets":"for user_1","as":"admin_1"}
$ curl 'localhost:3000/user_api/admin_1/widgets?token=admin_1'
class AppController < AC::Base
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class Err < Struct.new(:ctr, :err)
end
class Err < Struct.new(:ctr, :err)
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
class AppController < AC::Base
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
rescue_from StandardError do |error|
Err.new(self, error).run
end
rescue_from AC::ParameterMissing do |error|
render json: { error: error.message }
end
rescue_from AR::RecordNotFound do |error|
render json: { error: error.message }
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
rescue_from StandardError do |error|
Err.new(self, error).run
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
rescue_from StandardError do |error|
Err.new(self, error).run
end
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class Err < Struct.new(:ctr, :err)
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
class Err < Struct.new(:ctr, :err)
Rescue = lambda do |err|
Err.new(self, err).run
end
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
class AppController < AC::Base
rescue_from StandardError, &Err::Rescue
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class AppController < AC::Base
rescue_from StandardError, &Err::Rescue
private
attr_reader :current_user, :true_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def allow_ghosting
return unless current_user.admin?
if (ghost_token = params[:ghost])
ghost_target = User
.find_by_token!(ghost_token)
@true_user = @current_user
@current_user = ghost_target
end
end
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
module AdminApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AppController
rescue_from StandardError, &Err::Rescue
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
module Auth
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
else
raise err
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
when Auth::Unauthenticated
ctr.render json: { error: "No Auth" }
else
raise err
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
end
class Err < Struct.new(:ctr, :err)
Rescue = ->(err) { Err.new(self, err).run }
def run
case err
when AC::ParameterMissing
ctr.render json: { error: err.message }
when AR::RecordNotFound
ctr.render json: { error: err.message }
when Auth::Unauthenticated
ctr.render json: { error: "No Auth" }
when Auth::Unauthorized
ctr.render json: { error: "Forbidden" }
else
raise err
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
end
class Err < Struct.new(:ctr, :err)
# ...
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
end
class Err < Struct.new(:ctr, :err)
# ...
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
def self.before(ctr)
end
end
class Err < Struct.new(:ctr, :err)
# ...
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
def self.before(ctr)
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
class Err < Struct.new(:ctr, :err)
# ...
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
def self.before(ctr)
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action :set_current_user
before_action :auth_admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
def after_auth(user)
@current_user = user
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
def after_auth(user)
@current_user = user
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def set_current_user
token = params.require(:token)
user = User.find_by_token!(token)
@current_user = user
end
def auth_admin
unless current_user.admin?
render json: { error: "Forbidden" }
end
end
def after_auth(user)
@current_user = user
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
end
end
$
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=user_1'
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=user_1'
{"error":"Forbidden"}
$
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=user_1'
{"error":"Forbidden"}
$ curl 'localhost:3000/admin_api/widgets?token=invalid'
$ curl 'localhost:3000/admin_api/widgets?token=admin_1'
{"widgets":"all","as":"admin_1"}
$ curl 'localhost:3000/admin_api/widgets?token=user_1'
{"error":"Forbidden"}
$ curl 'localhost:3000/admin_api/widgets?token=invalid'
{"error":"No Auth"}
$
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
def self.before(ctr)
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
def self.before(ctr)
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth
# ...
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::Admin
# ...
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
def id_user
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
token = ctr.params.require(:token)
user = User.find_by_token!(token)
rescue
raise Unauthenticated
else
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
if user.admin?
ctr.send(:after_auth, user)
else
raise Unauthorized
end
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
if id_user.admin?
ctr.send(:after_auth, id_user)
else
raise Unauthorized
end
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr)
new(ctr).auth!
end
def auth!
if id_user.admin?
ctr.send(:after_auth, id_user)
else
raise Unauthorized
end
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Admin < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
class Admin < Base
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
class Admin < Base
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
raise NotImplementedError
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
raise NotImplementedError
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
raise NotImplementedError
end
def id_user
token = ctr.params.require(:token)
@id_user ||= User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
class User < Base
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
def self.before(ctr) new(ctr).auth! end
def auth!
raise NotImplementedError
end
def id_user
token = ctr.params.require(:token)
@id_user ||= ::User.find_by_token!(token)
rescue
raise Unauthenticated
else
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
class User < Base
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
# ...
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
class User < Base
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
# ...
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
class User < Base
def auth!
end
end
end
module Auth
Unauthenticated = Class.new(StandardError)
Unauthorized = Class.new(StandardError)
class Base < Struct.new(:ctr)
# ...
end
class Admin < Base
def auth!
id_user.admin? or raise Unauthorized
ctr.send(:after_auth, id_user)
end
end
class User < Base
def auth!
r_user = ctr.send(:resource_user)
if r_user == id_user || id_user.admin?
ctr.send(:after_auth, id_user)
else
raise Unauthorized
end
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module UserApi
class WidgetsController < AppController
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module UserApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module UserApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class WidgetsController < AppController
before_action :set_current_user
before_action :auth_user
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
def auth_user
unless current_user == resource_user ||
current_user.admin?
render json: { error: "Forbidden" }
end
end
end
end
module UserApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
end
end
module AdminApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::Admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
end
end
module UserApi
class WidgetsController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module AdminApi
class BaseController < AC::Base
end
class WidgetsController < BaseController
rescue_from StandardError, &Err::Rescue
before_action Auth::Admin
def index
render json: Widget.all
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
end
end
module UserApi
class BaseController < AC::Base
end
class WidgetsController < BaseController
rescue_from StandardError, &Err::Rescue
before_action Auth::User
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
end
module UserApi
class BaseController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::User
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
def resource_user
@resource_user ||= User.find_by_token!(
params.require(:user_id)
)
end
end
class WidgetsController < BaseController
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
end
end
module AdminApi
class BaseController < AC::Base
rescue_from StandardError, &Err::Rescue
before_action Auth::Admin
private
attr_reader :current_user
def after_auth(user)
@current_user = user
end
end
class WidgetsController < BaseController
def index
render json: Widget.all
.merge(as: current_user.token)
end
end
end
module UserApi
class BaseController < AC::Base
# ...
end
class WidgetsController < BaseController
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
end
end
module AdminApi
class BaseController < AC::Base
# ...
end
class WidgetsController < BaseController
def index
render json: Widget.all
.merge(as: current_user.token)
end
end
end
module UserApi
class BaseController < AC::Base
# ...
end
class WidgetsController < BaseController
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
end
class GizmosController < BaseController
# ...
end
end
module UserApi
class BaseController < AC::Base
# ...
end
class WidgetsController < BaseController
def index
render json: Widget.for(resource_user)
.merge(as: current_user.token)
end
end
class GizmosController < BaseController
# ...
end
class DoodadsController < BaseController
# ...
end
end
module AdminApi
class BaseController < AC::Base
# ...
end
class WidgetsController < BaseController
def index
render json: Widget.all
.merge(as: current_user.token)
end
end
class GizmosController < BaseController
# ...
end
class DoodadsController < BaseController
# ...
end
end
class Err
end
module Auth
class Base
class User < Base
class Admin < Base
end
module UserApi
class BaseController < AC::Base
class WidgetsController < BaseController
class GizmosController < BaseController
class DoodadsController < BaseController
end
module AdminApi
class BaseController < AC::Base
class WidgetsController < BaseController
class GizmosController < BaseController
class DoodadsController < BaseController
end
Reflektive App
Error Handling
Authentication/Authorization
Admin
API
User
API
Reflektive Core
Datastore