diff options
Diffstat (limited to 'bin/api')
| -rwxr-xr-x | bin/api | 114 |
1 files changed, 114 insertions, 0 deletions
@@ -0,0 +1,114 @@ +#!/usr/bin/env ruby + +require 'bundler/inline' + +gemfile do + source 'https://rubygems.org' + + gem "erb", "~> 4.0" + gem "json", "~> 2.0" + gem "rack", "~> 3.0" + gem "rackup", "~> 2.0" + gem "securerandom", "~> 0.1" + gem "webrick", "~> 1.0" +end + +$scheme = ENV.fetch('SCHEME', 'http') +$port = ENV.fetch('PORT', 8284).to_i +$host = ENV.fetch('HOST', "localhost:#{$port}") + +class Project + class << self + def all + @projects ||= [] + 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 to_h + @attributes + end +end + +class API + def call(env) + request = Rack::Request.new(env) + path = env['PATH_INFO'] + case env['REQUEST_METHOD'] + when 'GET' + case path + when '/projects.json' + return json_ok(Project.all.map(&:to_h)) + else + return json_not_found + end + when 'POST' + case path + when "/projects" + if authorized?(request, :create_project) + return json_created(Project.create!(JSON.parse(request.body.read, symbolize_names: true))) + else + return json_unauthorized(:create_project) + end + else + return json_not_found + end + end + json_not_found + end + + private + + def authorized?(request, permission) + # TODO:: Check the JWT for the appropriate claim + # Connect to the Authz RPC endpoint Ability.allowed?(subject, permission, resource) + true + 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) + http_response(code: 401, body: JSON.pretty_generate({ + error: { + code: 401, + message: "`#{permission}` is required", + } + })) + end + + def http_response(code:, headers: { 'Content-Type' => 'application/json' }, body: nil) + [ + code, + headers.merge({ 'X-Backend-Server' => 'REST' }), + [body].compact + ] + end +end + +if __FILE__ == $0 + app = Rack::Builder.new do + use Rack::Reloader + run API.new + end.to_app + + Rackup::Server.start(app: app, Port: $port) +end |
