diff options
Diffstat (limited to 'bin/api')
| -rwxr-xr-x | bin/api | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/bin/api b/bin/api deleted file mode 100755 index 180aa874..00000000 --- a/bin/api +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env ruby - -require 'bundler/inline' - -gemfile do - source 'https://rubygems.org' - - gem "csv", "~> 3.0" - gem "declarative_policy", "~> 1.0" - gem "erb", "~> 4.0" - gem "globalid", "~> 1.0" - gem "google-protobuf", "~> 3.0" - gem "json", "~> 2.0" - gem "logger", "~> 1.0" - gem "rack", "~> 3.0" - gem "rackup", "~> 2.0" - gem "securerandom", "~> 0.1" - gem "twirp", "~> 1.0" - gem "webrick", "~> 1.0" -end - -lib_path = Pathname.new(__FILE__).parent.parent.join('lib').realpath.to_s -$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path) - -require 'authx/rpc' - -$scheme = ENV.fetch("SCHEME", "http") -$port = ENV.fetch("PORT", 8284).to_i -$host = ENV.fetch("HOST", "localhost:#{$port}") - -class Entity - class << self - def all - @items ||= ::CSV.read(File.join(__dir__, "../db/api/#{self.name.downcase}s.csv"), headers: true).map do |row| - new(row.to_h.transform_keys(&:to_sym)) - end - end - - def create!(attributes) - new({ id: SecureRandom.uuid }.merge(attributes)).tap do |item| - all << item - end - end - end - - def initialize(attributes = {}) - @attributes = attributes - end - - def id - self[:id] - end - - def [](attribute) - @attributes.fetch(attribute.to_sym) - end - - def to_h - @attributes - end - - def to_gid - ::GlobalID.create(self, app: "example") - end -end - -class Organization < Entity - class << self - def default - @default ||= all.find { |organization| organization[:name] == "default" } - end - end -end - -class Group < Entity -end - -class Project < Entity -end - -module HTTPHelpers - def authorized?(request, permission, resource) - raise [permission, resource].inspect if resource.nil? - authorization = Rack::Auth::AbstractRequest.new(request.env) - return false unless authorization.provided? - - response = rpc.allowed({ - subject: authorization.params, - permission: permission, - resource: resource.to_gid.to_s, - }, headers: { 'Authorization' => "Bearer #{authorization.params}"}) - puts [response&.data&.result, permission, resource.to_gid.to_s].inspect - response.error.nil? && response.data.result - end - - def json_not_found - http_response(code: 404) - end - - def json_ok(body) - http_response(code: 200, body: JSON.pretty_generate(body)) - end - - def json_created(body) - http_response(code: 201, body: JSON.pretty_generate(body.to_h)) - end - - def json_unauthorized(permission, resource) - http_response(code: 401, body: JSON.pretty_generate({ - error: { - code: 401, - message: "`#{permission}` is required on `#{resource.to_gid}`", - } - })) - end - - def http_response(code:, headers: { 'Content-Type' => 'application/json' }, body: nil) - [ - code, - headers.merge({ 'X-Backend-Server' => 'REST' }), - [body].compact - ] - end -end - -class API - include HTTPHelpers - - attr_reader :rpc - - def initialize - @rpc = ::Authx::Rpc::AbilityClient.new("http://idp.example.com:8080/twirp") - end - - def call(env) - request = Rack::Request.new(env) - case request.request_method - when Rack::GET - case request.path - when "/organizations", "/organizations.json" - return json_ok(Organization.all.map(&:to_h)) - when "/groups", "/groups.json" - resource = Organization.default - if authorized?(request, :read_group, resource) - return json_ok(Group.all.map(&:to_h)) - else - return json_unauthorized(:read_group, resource) - end - when "/projects", "/projects.json" - resource = Organization.default - if authorized?(request, :read_project, resource) - return json_ok(Project.all.map(&:to_h)) - else - return json_unauthorized(:read_project, resource) - end - end - when Rack::POST - case request.path - when "/projects", "/projects.json" - resource = Organization.default - if authorized?(request, :create_project, resource) - return json_created(Project.create!(JSON.parse(request.body.read, symbolize_names: true))) - else - return json_unauthorized(:create_project, resource) - end - end - end - json_not_found - end - - private -end - -if __FILE__ == $0 - app = Rack::Builder.new do - use Rack::CommonLogger - use Rack::Reloader - run API.new - end.to_app - - Rackup::Server.start(app: app, Port: $port) -end |
