shaf 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a160e3aeb1d9b86b59371417e6354d351acfbe9a90efde270b51a1fe2a307a88
4
- data.tar.gz: d3c9eec43a5b5da8795e1e9396f8916be2458d235a14296c75646be25680b658
3
+ metadata.gz: 45e90f32663688a63993bcf1aa79c6c9b8667d11dbfc9a5fdba50141e983ea53
4
+ data.tar.gz: 919292b331cc09ce95031e4d1e723371114fef9e86b6d97c2e90e816befb0d77
5
5
  SHA512:
6
- metadata.gz: '093623e69f3fdf57124cdabd6b01c00129fe77e479ec54aa5d3fdef252ec92fa93895b99708ca7c831421c11c838dbe9e034acec9546c96fc1a5f6197bd39211'
7
- data.tar.gz: 4305a775fff58412125a1c984d27617c87fdd3d0fa1f20b798f6b47978aeafb34996bcd8f67b97f6ac1e3e1a2f117bf55c33f4e615af10bc0fdf917d61730231
6
+ metadata.gz: 788b01fd3f933f9e86ef99c9b51c14768208f73c5dc3cf4fe0a39fcb19078f82eb7eaaa2a1dcfc33d4d1a44980dc66254693a240b2e2b28d4a6e6b0d0383b676
7
+ data.tar.gz: a07510311e28e5008991d5461f9c2e97485640cd146a8304874bc216888eb722c941c266dc74b59b184ca3ea302b6a508a315421ed040dd64c2d111ea80548c7
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,11 +1,15 @@
1
1
  require 'shaf/extensions/resource_uris'
2
+ require 'shaf/extensions/current_user'
2
3
  require 'shaf/extensions/authorize'
4
+ require 'shaf/extensions/symbolic_routes'
3
5
 
4
6
  module Shaf
5
7
  def self.extensions
6
8
  [
7
9
  ResourceUris,
10
+ CurrentUser,
8
11
  Authorize,
12
+ SymbolicRoutes
9
13
  ]
10
14
  end
11
15
  end
@@ -19,7 +19,7 @@ module Shaf
19
19
 
20
20
  module Helpers
21
21
  def policy(resource)
22
- return @policy if @policy
22
+ return @policy if defined?(@policy) && @policy
23
23
  user = current_user if respond_to? :current_user
24
24
  @policy = self.class.policy_class&.new(user, resource)
25
25
  end
@@ -0,0 +1,44 @@
1
+ require 'digest'
2
+
3
+ module Shaf
4
+ module CurrentUser
5
+ def self.registered(app)
6
+ return unless app.respond_to?(:current_user) && app.current_user
7
+
8
+ app.log.info 'Using Shaf::CurrentUser'
9
+ app.helpers Helpers
10
+ end
11
+
12
+ def lookup_user_with(&block)
13
+ unless block_given? && block.respond_to?(:call)
14
+ raise ArgumentError, '::lookup_user_with requires a block argument'
15
+ end
16
+ log.info 'Using custom current_user lookup'
17
+ Helpers.lookup_proc = block
18
+ end
19
+ end
20
+
21
+ module Helpers
22
+ class << self
23
+ attr_accessor :lookup_proc
24
+
25
+ def user_lookup(request, token)
26
+ return lookup_proc.call(token, request) if lookup_proc
27
+ return unless token
28
+ digest = Digest::SHA256.hexdigest(token)
29
+ User.where(auth_token_digest: digest).first
30
+ end
31
+ end
32
+
33
+ def current_user
34
+ return @current_user if defined?(@current_user)
35
+ header = settings.auth_token_header
36
+ token = request.env[header]
37
+ @current_user = Helpers.user_lookup(request, token)
38
+ end
39
+
40
+ def authenticated?
41
+ !current_user.nil?
42
+ end
43
+ end
44
+ end
@@ -4,7 +4,8 @@ module Shaf
4
4
  module ResourceUris
5
5
  def resource_uris_for(*args)
6
6
  CreateUriMethods.new(*args).call
7
- include UriHelper
7
+
8
+ include UriHelper unless self < UriHelper
8
9
  end
9
10
 
10
11
  def register_uri(name, uri)
@@ -13,6 +14,9 @@ module Shaf
13
14
  end
14
15
  method_string = MethodBuilder.as_string(name, uri)
15
16
  UriHelperMethods.eval_method(method_string)
17
+ UriHelperMethods.register(MethodBuilder.template_method_name(name)) { uri.dup.freeze }
18
+
19
+ include UriHelper unless self < UriHelper
16
20
  end
17
21
  end
18
22
 
@@ -31,6 +35,10 @@ module Shaf
31
35
  module UriHelper
32
36
  extend UriHelperMethods
33
37
  include UriHelperMethods
38
+
39
+ def self.included(mod)
40
+ mod.extend self
41
+ end
34
42
  end
35
43
 
36
44
  # This class register uri helper methods like:
@@ -39,6 +47,12 @@ module Shaf
39
47
  # new_book_uri => /books/form
40
48
  # edit_book_uri(book) => /books/5/edit
41
49
  #
50
+ # And uri template methods:
51
+ # books_uri_template => /books
52
+ # book_uri_template => /books/:id
53
+ # new_book_uri_template => /books/form
54
+ # edit_book_uri_template => /books/:id/edit
55
+ #
42
56
  class CreateUriMethods
43
57
  def initialize(name, base: nil, plural_name: nil)
44
58
  @name = name.to_s
@@ -62,17 +76,23 @@ module Shaf
62
76
  attr_reader :name, :base, :plural_name
63
77
 
64
78
  def register_resources_uri
65
- uri = "#{base}/#{plural_name}"
66
- UriHelperMethods.register "#{plural_name}_uri" do
67
- uri.dup.freeze
68
- end
79
+ uri = "#{base}/#{plural_name}".freeze
80
+
81
+ UriHelperMethods.register("#{plural_name}_uri") { uri }
82
+ UriHelperMethods.register("#{plural_name}_uri_template") { uri }
69
83
  end
70
84
 
71
85
  def register_resource_uri
72
86
  uri = "#{base}/#{plural_name}"
87
+
73
88
  UriHelperMethods.register "#{name}_uri" do |resrc|
74
89
  id = resrc.is_a?(Integer) ? resrc : resrc&.id
75
- "#{uri}/#{id}".freeze unless id.nil?
90
+ raise ArgumentError, "id must be an integer! was #{id.class}" unless id.is_a?(Integer)
91
+ "#{uri}/#{id}".freeze
92
+ end
93
+
94
+ UriHelperMethods.register "#{name}_uri_template" do
95
+ "#{uri}/:id".freeze
76
96
  end
77
97
  end
78
98
 
@@ -83,27 +103,37 @@ module Shaf
83
103
  uri = "#{base}/#{plural_name}"
84
104
  UriHelperMethods.register "#{plural_name}_uri" do |resrc = nil|
85
105
  if resrc.nil?
86
- uri.dup.freeze
106
+ uri.freeze
87
107
  else
88
- id = resrc.is_a?(Integer) ? resrc : resrc&.id
89
- "#{uri}/#{id}".freeze unless id.nil?
108
+ id = (resrc.is_a?(Integer) ? resrc : resrc.id).to_i
109
+ raise ArgumentError, "id must be an integer! was #{id.class}" unless id.is_a?(Integer)
110
+ "#{uri}/#{id}".freeze
90
111
  end
91
112
  end
113
+
114
+ UriHelperMethods.register "#{plural_name}_uri_template" do |collection = false|
115
+ (collection ? uri : "#{uri}/:id").freeze
116
+ end
92
117
  end
93
118
 
94
119
  def register_new_resource_uri
95
- uri = "#{base}/#{plural_name}/form"
96
- UriHelperMethods.register "new_#{name}_uri" do
97
- uri.dup.freeze
98
- end
120
+ uri = "#{base}/#{plural_name}/form".freeze
121
+
122
+ UriHelperMethods.register("new_#{name}_uri") { uri }
123
+ UriHelperMethods.register("new_#{name}_uri_template") { uri }
99
124
  end
100
125
 
101
126
  def register_edit_resource_uri
102
127
  uri = "#{base}/#{plural_name}"
128
+
103
129
  UriHelperMethods.register "edit_#{name}_uri" do |resrc|
104
130
  id = resrc.is_a?(Integer) ? resrc : resrc&.id
105
131
  "#{uri}/#{id}/edit".freeze unless id.nil?
106
132
  end
133
+
134
+ UriHelperMethods.register "edit_#{name}_uri_template" do
135
+ "#{uri}/:id/edit".freeze
136
+ end
107
137
  end
108
138
  end
109
139
 
@@ -113,6 +143,10 @@ module Shaf
113
143
  "#{name}_uri"
114
144
  end
115
145
 
146
+ def template_method_name(name)
147
+ "#{method_name(name)}_template"
148
+ end
149
+
116
150
  def signature(name, uri)
117
151
  args = extract_symbols(uri)
118
152
  s = method_name(name)
@@ -0,0 +1,27 @@
1
+ module Shaf
2
+ module SymbolicRoutes
3
+ [
4
+ :get,
5
+ :put,
6
+ :post,
7
+ :patch,
8
+ :delete,
9
+ :head,
10
+ :options,
11
+ :link,
12
+ :unlink
13
+ ].each do |m|
14
+ define_method m do |path, &block|
15
+ super(rewrite_path(path), &block)
16
+ end
17
+ end
18
+
19
+ def rewrite_path(path)
20
+ return path unless path.is_a? Symbol
21
+
22
+ m = "#{path}_template"
23
+ raise "Don't know how to 'get #{path}'" unless respond_to? m
24
+ send m
25
+ end
26
+ end
27
+ end
@@ -1,7 +1,12 @@
1
1
  module Shaf
2
2
  module Formable
3
3
  class Field
4
- attr_reader :name, :type, :value, :label
4
+ attr_reader :name, :type, :value, :label, :required
5
+
6
+ HTML_TYPE_MAPPINGS = {
7
+ 'string' => 'text',
8
+ 'boolean' => 'checkbox',
9
+ }.freeze
5
10
 
6
11
  def initialize(name, params = {})
7
12
  @name = name
@@ -9,6 +14,7 @@ module Shaf
9
14
  @label = params[:label]
10
15
  @has_value = params.key? :value
11
16
  @value = params[:value]
17
+ @required = params[:required] || false
12
18
  end
13
19
 
14
20
  def has_value?
@@ -32,8 +38,18 @@ module Shaf
32
38
  end
33
39
 
34
40
  def input_element
35
- _value = value ? %Q( value="#{value.to_s}") : ""
36
- %Q(<input type="#{type.to_s}" class="form--input" id="#{name.to_s}" name="#{name.to_s}"#{_value}>)
41
+ _value = value ? %Q(value="#{value.to_s}") : nil
42
+ _required = required ? "required" : nil
43
+ attributes = [
44
+ %Q(type="#{HTML_TYPE_MAPPINGS[type.to_s]}"),
45
+ 'class="form--input"',
46
+ %Q(id="#{name.to_s}"),
47
+ %Q(name="#{name.to_s}"),
48
+ ]
49
+ attributes << %Q(value="#{value.to_s}") if value
50
+ attributes << "required" if required
51
+
52
+ "<input #{attributes.join(" ")}>"
37
53
  end
38
54
  end
39
55
 
@@ -35,6 +35,7 @@ module Shaf
35
35
  def opts
36
36
  {
37
37
  policy_class_name: "#{policy_name.capitalize}Policy",
38
+ name: policy_name,
38
39
  attributes: attributes,
39
40
  }
40
41
  end
@@ -2,52 +2,50 @@ require '<%= policy_file %>'
2
2
 
3
3
  class <%= controller_class_name %> < BaseController
4
4
 
5
+ authorize_with <%= policy_class_name %>
6
+
5
7
  resource_uris_for :<%= name %>
6
8
 
7
- authorize_with <%= policy_class_name %>
9
+ get :<%= plural_name %>_uri do
10
+ authorize! :read
11
+ collection = paginate(<%= model_class_name %>.order(:created_at).reverse)
12
+ respond_with_collection collection, serializer: <%= serializer_class_name %>
13
+ end
8
14
 
9
- get '/<%= plural_name %>/form' do
10
- form = <%= model_class_name %>.create_form
11
- form.self_link = new_<%= name %>_uri
12
- form.href = <%= plural_name %>_uri
13
- respond_with form
15
+ get :new_<%= name %>_uri do
16
+ authorize! :read
17
+ respond_with create_form
14
18
  end
15
19
 
16
- get '/<%= plural_name %>/:id/edit' do
17
- form = <%= name %>.edit_form
18
- form.self_link = edit_<%= name %>_uri(<%= name %>)
19
- form.href = <%= name %>_uri(<%= name %>)
20
- respond_with form
20
+ post :<%= plural_name %>_uri do
21
+ authorize! :write
22
+ <%= name %> = <%= model_class_name %>.create(<%= name %>_params)
23
+ headers({ "Location" => <%= name %>_uri(<%= name %>) })
24
+ respond_with <%= name %>, status: 201
21
25
  end
22
26
 
23
- get '/<%= plural_name %>/:id' do
27
+ get :<%= name %>_uri do
28
+ authorize! :read
24
29
  respond_with <%= name %>
25
30
  end
26
31
 
27
- put '/<%= plural_name %>/:id' do
32
+ get :edit_<%= name %>_uri do
33
+ authorize! :read
34
+ respond_with edit_form
35
+ end
36
+
37
+ put :<%= name %>_uri do
28
38
  authorize! :write
29
39
  <%= name %>.update(<%= name %>_params)
30
40
  respond_with <%= name %>
31
41
  end
32
42
 
33
- delete '/<%= plural_name %>/:id' do
43
+ delete :<%= name %>_uri do
34
44
  authorize! :write
35
45
  <%= name %>.destroy
36
46
  status 204
37
47
  end
38
48
 
39
- get '/<%= plural_name %>' do
40
- collection = paginate(<%= model_class_name %>.order(:created_at).reverse)
41
- respond_with_collection collection, serializer: <%= serializer_class_name %>
42
- end
43
-
44
- post '/<%= plural_name %>' do
45
- authorize! :write
46
- <%= name %> = <%= model_class_name %>.create(<%= name %>_params)
47
- headers({ "Location" => <%= name %>_uri(<%= name %>) })
48
- respond_with <%= name %>, status: 201
49
- end
50
-
51
49
  def <%= name %>_params
52
50
  # Generated method - TODO: Remove any params that should not be allowed!
53
51
  safe_params(<%= params.map { |p| ":#{p[0]}" }.join(', ') %>)
@@ -59,4 +57,17 @@ class <%= controller_class_name %> < BaseController
59
57
  end
60
58
  end
61
59
 
60
+ def create_form
61
+ <%= model_class_name %>.create_form.tap do |form|
62
+ form.self_link = new_<%= name %>_uri
63
+ form.href = <%= plural_name %>_uri
64
+ end
65
+ end
66
+
67
+ def edit_form
68
+ <%= name %>.edit_form.tap do |form|
69
+ form.self_link = edit_<%= name %>_uri(<%= name %>)
70
+ form.href = <%= name %>_uri(<%= name %>)
71
+ end
72
+ end
62
73
  end
@@ -3,6 +3,8 @@ class <%= policy_class_name %>
3
3
 
4
4
  # Auto generated policy: Update this file to suite your API!
5
5
 
6
+ alias :<%= name %> :resource
7
+
6
8
  <%= attributes.join("\n ") %>
7
9
 
8
10
  link :up
@@ -16,11 +18,12 @@ class <%= policy_class_name %>
16
18
  end
17
19
 
18
20
  def read?
21
+ # FIXME!!
19
22
  true
20
23
  end
21
24
 
22
25
  def write?
23
- # !!current_user
26
+ # FIXME!!
24
27
  true
25
28
  end
26
29
  end
@@ -1,7 +1,6 @@
1
1
  require 'shaf/helpers/payload'
2
2
  require 'shaf/helpers/json_html'
3
3
  require 'shaf/helpers/paginate'
4
- require 'shaf/helpers/session'
5
4
 
6
5
  module Shaf
7
6
  def self.helpers
@@ -9,7 +8,6 @@ module Shaf
9
8
  Payload,
10
9
  JsonHtml,
11
10
  Paginate,
12
- Session,
13
11
  ]
14
12
  end
15
13
  end
@@ -1,5 +1,7 @@
1
1
  module Shaf
2
2
  module Payload
3
+ EXCLUDED_FORM_PARAMS = ['captures', 'splat'].freeze
4
+
3
5
  def supported_response_types(resource)
4
6
  [
5
7
  mime_type(:hal),
@@ -39,7 +41,7 @@ module Shaf
39
41
 
40
42
  def parse_payload
41
43
  if request.env['CONTENT_TYPE'] == 'application/x-www-form-urlencoded'
42
- return params.reject { |key,_| ['captures', 'splat'].include? key }
44
+ return params.reject { |key,_| EXCLUDED_FORM_PARAMS.include? key }
43
45
  end
44
46
 
45
47
  input = read_input
@@ -56,9 +58,11 @@ module Shaf
56
58
 
57
59
  def safe_params(*fields)
58
60
  return {} unless payload
61
+ field_strings = fields.map { |f| f.to_s.downcase }
62
+ field_strings << 'id' unless field_strings.include? 'id'
63
+
59
64
  {}.tap do |allowed|
60
- fields.each do |field|
61
- f = field.to_s.downcase
65
+ field_strings.each do |f|
62
66
  allowed[f.to_sym] = payload[f] if payload[f]
63
67
  end
64
68
  end
@@ -1,9 +1,9 @@
1
1
  module Shaf
2
2
  module Spec
3
- module HttpMethodUtils
3
+ module HttpUtils
4
4
  include ::Rack::Test::Methods
5
5
 
6
- [:get, :put, :post, :delete].each do |m|
6
+ [:get, :put, :patch, :post, :delete, :options, :head, :link, :unlink].each do |m|
7
7
  define_method m do |*args|
8
8
  set_headers
9
9
  super(*args)
@@ -16,9 +16,8 @@ module Shaf
16
16
  end
17
17
 
18
18
  def headers
19
- last_response&.headers
19
+ last_response&.headers || {}
20
20
  end
21
-
22
21
  end
23
22
  end
24
23
  end
@@ -2,7 +2,7 @@ module Shaf
2
2
  module Spec
3
3
  class IntegrationSpec < Minitest::Spec
4
4
  include Minitest::Hooks
5
- include HttpMethodUtils
5
+ include HttpUtils
6
6
  include PayloadUtils
7
7
  include UriHelper
8
8
 
@@ -30,6 +30,8 @@ module Shaf
30
30
  def parse_response(body)
31
31
  return nil if body.empty?
32
32
  JSON.parse(body, symbolize_names: true)
33
+ rescue JSON::ParserError => e
34
+ assert e.nil?, "Could not parse reponse as json"
33
35
  end
34
36
 
35
37
  def app
@@ -46,6 +48,13 @@ module Shaf
46
48
  end
47
49
  end
48
50
 
51
+ def auth_token(token)
52
+ @__integration_test_auth_token = token
53
+ end
54
+
55
+ def clear_auth_token
56
+ @__integration_test_auth_token = nil
57
+ end
49
58
 
50
59
  # def login(email, pass)
51
60
  # params = {email: email, password: pass}
@@ -3,42 +3,6 @@ require 'minitest/assertions'
3
3
  module Shaf
4
4
  module Spec
5
5
  module PayloadUtils
6
-
7
- class Embedded
8
- include HttpMethodUtils
9
- include PayloadUtils
10
- include Minitest::Assertions
11
-
12
- # This is needed by Minitest::Assertions
13
- # And we need that module to have all assert_*/refute_* methods
14
- # available in this class
15
- attr_accessor :assertions
16
-
17
- def initialize(payload, context, block)
18
- @payload = payload
19
- @context = context
20
- @block = block
21
- @assertions = 0
22
- end
23
-
24
- def call(*args)
25
- instance_exec(*args, &@block)
26
- end
27
-
28
- def method_missing(method, *args, &block)
29
- if @context&.respond_to? method
30
- define_singleton_method(method) { |*a, &b| @context.public_send(method, *a, &b) }
31
- return public_send(method, *args, &block)
32
- end
33
- super
34
- end
35
-
36
- def respond_to_missing?(method, include_private = false)
37
- return true if @context&.respond_to? method
38
- super
39
- end
40
- end
41
-
42
6
  def set_payload(payload)
43
7
  @payload = payload
44
8
  @payload = JSON.parse(payload, symbolize_names: true) if payload.is_a?(String)
@@ -69,7 +33,7 @@ module Shaf
69
33
  assert_has_embedded name unless name.nil?
70
34
  keys = [:_embedded, name&.to_sym].compact
71
35
  return last_payload.dig(*keys) unless block_given?
72
- Embedded.new(last_payload.dig(*keys), self, Proc.new).call
36
+ exec_embed_block(last_payload.dig(*keys), Proc.new)
73
37
  end
74
38
 
75
39
  def each_embedded(name, &block)
@@ -80,7 +44,7 @@ module Shaf
80
44
  "Embedded '#{name}' is not an instance of Array. Actual: #{list.class}"
81
45
 
82
46
  list.each_with_index do |resource, i|
83
- Embedded.new(resource, self, block).call(i)
47
+ exec_embed_block(resource, block, i)
84
48
  end
85
49
  end
86
50
 
@@ -172,6 +136,15 @@ module Shaf
172
136
  "Response contains disallowed embedded resource with name '#{name}': #{last_payload}"
173
137
  end
174
138
  end
139
+
140
+ private
141
+
142
+ def exec_embed_block(payload, block, *args)
143
+ prev_payload = last_payload
144
+ set_payload(payload)
145
+ instance_exec(*args, &block)
146
+ set_payload(prev_payload)
147
+ end
175
148
  end
176
149
  end
177
150
  end
@@ -5,24 +5,28 @@ namespace :test do |ns|
5
5
  t.libs = %w(. api spec)
6
6
  t.pattern = "spec/integration/**/*_spec.rb"
7
7
  t.verbose = true
8
+ t.warning = false
8
9
  end
9
10
 
10
11
  Rake::TestTask.new(:models) do |t|
11
12
  t.libs = %w(. api spec)
12
13
  t.pattern = "spec/models/**/*_spec.rb"
13
14
  t.verbose = true
15
+ t.warning = false
14
16
  end
15
17
 
16
18
  Rake::TestTask.new(:serializers) do |t|
17
19
  t.libs = %w(. api spec)
18
20
  t.pattern = "spec/serializers/**/*_spec.rb"
19
21
  t.verbose = true
22
+ t.warning = false
20
23
  end
21
24
 
22
25
  Rake::TestTask.new(:lib) do |t|
23
26
  t.libs = %w(. api spec)
24
27
  t.pattern = "spec/lib/**/*_spec.rb"
25
28
  t.verbose = true
29
+ t.warning = false
26
30
  end
27
31
 
28
32
  Rake::TestTask.new(:all) do |t|
@@ -34,6 +38,7 @@ namespace :test do |ns|
34
38
  "spec/integration/**/*_spec.rb"
35
39
  ]
36
40
  t.verbose = true
41
+ t.warning = false
37
42
  end
38
43
 
39
44
  end
@@ -1,3 +1,3 @@
1
1
  module Shaf
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -12,21 +12,28 @@ class BaseController < Sinatra::Base
12
12
  set :public_folder, ASSETS_DIR
13
13
  disable :dump_errors
14
14
  set :show_exceptions, :after_handler
15
+ enable :current_user
16
+ set :auth_token_header, AUTH_TOKEN_HEADER
15
17
  end
16
18
 
17
19
  use Rack::Deflater
18
- register(*Shaf.extensions)
19
- helpers(*Shaf.helpers)
20
20
 
21
21
  def self.inherited(controller)
22
22
  super
23
23
  Shaf::App.use controller
24
24
  end
25
25
 
26
- def log
26
+ def self.log
27
27
  $logger
28
28
  end
29
29
 
30
+ def log
31
+ self.class.log
32
+ end
33
+
34
+ register(*Shaf.extensions)
35
+ helpers(*Shaf.helpers)
36
+
30
37
  before do
31
38
  log.info "Processing: #{request.request_method} #{request.path_info}"
32
39
  log.debug "Payload: #{payload || 'empty'}"
@@ -1,12 +1,13 @@
1
1
  class DocsController < BaseController
2
2
 
3
- register_uri :doc_curie, '/doc/:resource/rels/{rel}'
3
+ register_uri :doc_curie, '/doc/:resource/rels/{rel}'
4
+ register_uri :documentation, '/doc/:resource'
4
5
 
5
- get '/doc/:resource/rels/:rel' do
6
+ get doc_curie_uri_template do
6
7
  doc.link(params[:rel])
7
8
  end
8
9
 
9
- get '/doc/:resource' do
10
+ get documentation_uri_template do
10
11
  doc.to_s
11
12
  end
12
13
 
@@ -2,7 +2,7 @@ class RootController < BaseController
2
2
 
3
3
  register_uri :root, '/'
4
4
 
5
- get '/' do
5
+ get root_uri do
6
6
  respond_with nil, serializer: RootSerializer
7
7
  end
8
8
  end
@@ -33,9 +33,13 @@ class FormSerializer
33
33
  fields = resource&.fields
34
34
  break if fields.nil? || fields.empty?
35
35
  hash[:fields] = fields.map do |field|
36
- { name: field.name, type: field.type }.tap do |f|
36
+ {
37
+ name: field.name,
38
+ type: field.type,
39
+ label: field.label,
40
+ }.tap do |f|
37
41
  f[:value] = field.value if field.has_value?
38
- f[:label] = field.label
42
+ f[:required] = true if field.required
39
43
  end
40
44
  end
41
45
  end
@@ -1,5 +1,7 @@
1
1
  APP_ROOT = File.expand_path('../', __dir__)
2
2
  APP_DIR = File.expand_path('api', APP_ROOT)
3
+ SRC_DIR = File.expand_path('src', APP_ROOT)
3
4
  VIEWS_DIR = File.join(APP_ROOT, Shaf::Settings.views_folder)
4
5
  ASSETS_DIR = File.join(APP_ROOT, Shaf::Settings.public_folder)
6
+ AUTH_TOKEN_HEADER = 'HTTP_X_AUTH_TOKEN'
5
7
  PAGINATION_PER_PAGE = Shaf::Settings.paginate_per_page || 25
@@ -21,7 +21,7 @@ def sort_files(files)
21
21
  end
22
22
  end
23
23
 
24
- Dir.chdir(APP_DIR) do
24
+ def require_ruby_files
25
25
  files = Dir[File.join('**', '*.rb')]
26
26
  sort_files(files).each do |file|
27
27
  # load all files with .rb extension in subfolders of api
@@ -30,3 +30,15 @@ Dir.chdir(APP_DIR) do
30
30
  end
31
31
  end
32
32
 
33
+ if Dir.exist? SRC_DIR
34
+ $:.unshift SRC_DIR
35
+
36
+ Dir.chdir(SRC_DIR) do
37
+ require_ruby_files
38
+ end
39
+ end
40
+
41
+ Dir.chdir(APP_DIR) do
42
+ require_ruby_files
43
+ end
44
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shaf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sammy Henningsson
@@ -31,7 +31,7 @@ cert_chain:
31
31
  CNZdF8Vavp6xMQbPHZwqjaeZz2WRXYS7jyYSvCunjwa3OtvXtfbIEGEWE6IM+t9k
32
32
  H1g6Q+B6qk9O6g==
33
33
  -----END CERTIFICATE-----
34
- date: 2018-03-14 00:00:00.000000000 Z
34
+ date: 2018-03-26 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
@@ -252,7 +252,9 @@ files:
252
252
  - lib/shaf/errors.rb
253
253
  - lib/shaf/extensions.rb
254
254
  - lib/shaf/extensions/authorize.rb
255
+ - lib/shaf/extensions/current_user.rb
255
256
  - lib/shaf/extensions/resource_uris.rb
257
+ - lib/shaf/extensions/symbolic_routes.rb
256
258
  - lib/shaf/formable.rb
257
259
  - lib/shaf/generator.rb
258
260
  - lib/shaf/generator/controller.rb
@@ -277,7 +279,6 @@ files:
277
279
  - lib/shaf/helpers/json_html.rb
278
280
  - lib/shaf/helpers/paginate.rb
279
281
  - lib/shaf/helpers/payload.rb
280
- - lib/shaf/helpers/session.rb
281
282
  - lib/shaf/middleware.rb
282
283
  - lib/shaf/middleware/request_id.rb
283
284
  - lib/shaf/registrable_factory.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,53 +0,0 @@
1
- require 'digest'
2
-
3
- module Shaf
4
- module Session
5
-
6
- SESSION_TTL = 60 * 60 * 24 * 2 # 2 days
7
-
8
- def login(email, password)
9
- return unless email && password
10
- user = User.first(email: email) or return
11
- bcrypt = BCrypt::Password.new(user.password_digest)
12
- return unless bcrypt == password
13
- @current_user = user
14
-
15
- Session.where(user_id: user.id).delete
16
- params = {
17
- user_id: user.id,
18
- expire_at: Time.now + SESSION_TTL,
19
- }
20
- Session.create(params)
21
- end
22
-
23
- def extend_session(session)
24
- return unless session
25
- session.update(expire_at: Time.now + SESSION_TTL)
26
- session.auth_token = request.env['HTTP_X_AUTH_TOKEN']
27
- session
28
- end
29
-
30
- def logout
31
- current_session&.destroy
32
- end
33
-
34
- def current_user
35
- unless defined?(@current_user) && @current_user
36
- return unless request.env.key? 'HTTP_X_AUTH_TOKEN'
37
- digest = Digest::SHA256.hexdigest(request.env['HTTP_X_AUTH_TOKEN'])
38
- session = Session.where(auth_token_digest: digest).first
39
- @current_user = User[session.user_id] if session&.valid?
40
- end
41
- @current_user
42
- end
43
-
44
- def current_session
45
- unless @current_session
46
- return unless current_user
47
- @current_session = Session.where(user_id: current_user.id).first
48
- end
49
- @current_session
50
- end
51
-
52
- end
53
- end