shogun 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/bin/shogun +18 -0
  3. data/lib/shogun.rb +29 -0
  4. data/lib/shogun/authorizer.rb +7 -0
  5. data/lib/shogun/control.rb +82 -0
  6. data/lib/shogun/control/null.rb +15 -0
  7. data/lib/shogun/database.rb +44 -0
  8. data/lib/shogun/denormalizer.rb +54 -0
  9. data/lib/shogun/dispatch.rb +67 -0
  10. data/lib/shogun/dispatch/lookup.rb +57 -0
  11. data/lib/shogun/dispatch/payload.rb +18 -0
  12. data/lib/shogun/dispatch/route.rb +34 -0
  13. data/lib/shogun/dispatch/route/null.rb +11 -0
  14. data/lib/shogun/endpoint.rb +11 -0
  15. data/lib/shogun/normalizer.rb +31 -0
  16. data/lib/shogun/presenter.rb +57 -0
  17. data/lib/shogun/presenters.rb +28 -0
  18. data/lib/shogun/server.rb +49 -0
  19. data/lib/shogun/validator.rb +15 -0
  20. data/lib/shogun/verifier.rb +9 -0
  21. data/lib/shogun/verifier/allowed.rb +29 -0
  22. data/lib/shogun/verifier/match.rb +31 -0
  23. data/lib/shogun/verifier/presence.rb +26 -0
  24. data/lib/shogun/verifier/range.rb +30 -0
  25. data/lib/shogun/verifier/uniqueness.rb +23 -0
  26. data/lib/shogun/version.rb +3 -0
  27. data/spec/lib/shogun/authorizer_spec.rb +5 -0
  28. data/spec/lib/shogun/control/null_spec.rb +5 -0
  29. data/spec/lib/shogun/control_spec.rb +5 -0
  30. data/spec/lib/shogun/database_spec.rb +5 -0
  31. data/spec/lib/shogun/denormalizer_spec.rb +5 -0
  32. data/spec/lib/shogun/dispatch/lookup_spec.rb +5 -0
  33. data/spec/lib/shogun/dispatch/payload_spec.rb +5 -0
  34. data/spec/lib/shogun/dispatch/route/null_spec.rb +5 -0
  35. data/spec/lib/shogun/dispatch/route_spec.rb +5 -0
  36. data/spec/lib/shogun/dispatch_spec.rb +5 -0
  37. data/spec/lib/shogun/endpoint_spec.rb +5 -0
  38. data/spec/lib/shogun/normalizer_spec.rb +5 -0
  39. data/spec/lib/shogun/presenter_spec.rb +5 -0
  40. data/spec/lib/shogun/presenters_spec.rb +5 -0
  41. data/spec/lib/shogun/server_spec.rb +5 -0
  42. data/spec/lib/shogun/validator_spec.rb +5 -0
  43. data/spec/lib/shogun/verifier/allowed_spec.rb +5 -0
  44. data/spec/lib/shogun/verifier/match_spec.rb +5 -0
  45. data/spec/lib/shogun/verifier/presence_spec.rb +5 -0
  46. data/spec/lib/shogun/verifier/range_spec.rb +5 -0
  47. data/spec/lib/shogun/verifier/uniqueness_spec.rb +5 -0
  48. data/spec/lib/shogun/verifier_spec.rb +5 -0
  49. data/spec/lib/shogun_spec.rb +5 -0
  50. data/spec/spec_helper.rb +6 -0
  51. metadata +385 -0
@@ -0,0 +1,11 @@
1
+ module Shogun
2
+ class Dispatch
3
+ class Route
4
+ class Null
5
+ def control
6
+ Shogun::Control::Null
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Shogun
2
+ module Endpoint
3
+ private def route(verb:, matcher: nil, control:)
4
+ Dispatch::Route.new(namespace: namespace, verb: verb, matcher: matcher, control: control)
5
+ end
6
+
7
+ private def namespace
8
+ self.class.const_get("NAMESPACE")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ module Shogun
2
+ module Normalizer
3
+ def to_hash
4
+ attributes.inject({}) do |hash, attribute|
5
+ if public_send(attribute)
6
+ hash.merge(attribute => public_send(attribute))
7
+ else
8
+ hash
9
+ end
10
+ end
11
+ end
12
+
13
+ def as_meta
14
+ metadata.inject({}) do |hash, meta|
15
+ if public_send(meta)
16
+ hash.merge(meta => public_send(meta))
17
+ else
18
+ hash
19
+ end
20
+ end
21
+ end
22
+
23
+ private def attributes
24
+ self.class.const_get("ATTRIBUTES")
25
+ end
26
+
27
+ private def metadata
28
+ self.class.const_get("METADATA")
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ module Shogun
2
+ module Presenter
3
+ def initialize(resource:, meta: {}, links: {}, linked: {})
4
+ @source = resource
5
+ @meta = meta
6
+ @links = links
7
+ @linked = linked
8
+ end
9
+
10
+ def href
11
+ [host, namespace, id].join("/")
12
+ end
13
+
14
+ def meta
15
+ @meta
16
+ end
17
+
18
+ def linked
19
+ @linked
20
+ end
21
+
22
+ def links
23
+ @links.tap do |hash|
24
+ associations.each do |name|
25
+ case association(name).macro
26
+ when :has_many
27
+ hash.store(name, source.public_send(name).pluck(:id))
28
+ when :belongs_to
29
+ hash.store(name, source.public_send(association(name).foreign_key))
30
+ when :has_one
31
+ hash.store(name, source.public_send(name).pluck(:id))
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ private def host
38
+ ENV["API_HOST"]
39
+ end
40
+
41
+ private def associations
42
+ self.class.const_get("ASSOCIATIONS")
43
+ end
44
+
45
+ private def namespace
46
+ self.class.const_get("NAMESPACE")
47
+ end
48
+
49
+ private def association(name)
50
+ source.class.reflections[name.to_sym]
51
+ end
52
+
53
+ private def source
54
+ @source
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ module Shogun
2
+ class Presenters
3
+ def initialize(resources:, cast:, meta: {}, links: {}, linked: {})
4
+ @sources = resources.map do |resource|
5
+ cast.new(resource: resource)
6
+ end
7
+ @meta = meta
8
+ @links = links
9
+ @linked = linked
10
+ end
11
+
12
+ def map(&block)
13
+ @sources.map(&block)
14
+ end
15
+
16
+ def meta
17
+ @meta
18
+ end
19
+
20
+ def linked
21
+ @linked
22
+ end
23
+
24
+ def links
25
+ @links
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ module Shogun
2
+ module Server
3
+ def serve
4
+ @rack.use(Rack::Lineprof) if ENV["RACK_ENV"] == "development"
5
+ @rack.use(Rack::Log, @logger)
6
+ @rack.use(Rack::Runtime)
7
+ @rack.use(ActiveRecord::ConnectionAdapters::ConnectionManagement)
8
+ @rack.use(ActiveRecord::QueryCache)
9
+ @rack.use(Rack::Chunker)
10
+ @rack.use(Rack::AcceptSetter, accept_types)
11
+ @rack.use(Rack::ContentLengthSetter)
12
+ @rack.use(Rack::AuthenticationBearer, &bearer)
13
+ @rack.use(Rack::BodyDeserializer, deserialization_map)
14
+ @rack.use(Rack::BodySerializer, serialization_map, default_serializer)
15
+ @rack.use(Rack::Protection::RemoteReferrer)
16
+ @rack.use(Rack::Protection::HttpOrigin)
17
+ @rack.use(Rack::Protection::EscapedParams)
18
+ @rack.use(Rack::Protection::XSSHeader)
19
+ @rack.use(Rack::Protection::FrameOptions)
20
+ @rack.use(Rack::Protection::PathTraversal)
21
+ @rack.use(Rack::Protection::IPSpoofing)
22
+ @rack.run(Shogun::Dispatch.new(logger: @logger, &endpoints))
23
+ end
24
+
25
+ private def endpoints
26
+ self.class.const_get("ENDPOINTS")
27
+ end
28
+
29
+ private def deserialization_map
30
+ self.class.const_get("DESERIALIZATION_MAP")
31
+ end
32
+
33
+ private def bearer
34
+ self.class.const_get("BEARER")
35
+ end
36
+
37
+ private def serialization_map
38
+ self.class.const_get("SERIALIZATION_MAP")
39
+ end
40
+
41
+ private def default_serializer
42
+ self.class.const_get("DEFAULT_SERIALIZER")
43
+ end
44
+
45
+ private def accept_types
46
+ self.class.const_get("ACCEPT_TYPES")
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module Shogun
2
+ module Validator
3
+ def valid?
4
+ verifiers.all?(&:valid?)
5
+ end
6
+
7
+ def to_array
8
+ verifiers.reject(&:valid?)
9
+ end
10
+
11
+ private def verifiers
12
+ @verifiers
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Shogun
2
+ module Verifier
3
+ require_relative "verifier/allowed"
4
+ require_relative "verifier/match"
5
+ require_relative "verifier/presence"
6
+ require_relative "verifier/range"
7
+ require_relative "verifier/uniqueness"
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Shogun
2
+ module Verifier
3
+ class Allowed
4
+ def initialize(name:, data:, list: [])
5
+ @data = data
6
+ @name = name
7
+ @list = list || []
8
+ end
9
+
10
+ def valid?
11
+ @data.all?(&method(:allowed?))
12
+ end
13
+
14
+ def id
15
+ "#{@name}_not_allowed"
16
+ end
17
+
18
+ def context
19
+ {
20
+ "unallowed" => @data.reject(&method(:allowed?))
21
+ }
22
+ end
23
+
24
+ private def allowed?(item)
25
+ @list.include?(item)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ module Shogun
2
+ module Verifier
3
+ class Match
4
+ def initialize(data:, name:, comparison:)
5
+ @data = data
6
+ @name = name
7
+ @comparison = comparison
8
+ end
9
+
10
+ def valid?
11
+ if @comparison.is_a?(Regexp)
12
+ @data =~ @comparison
13
+ else
14
+ @data == @comparison || @comparison == @data
15
+ end
16
+ end
17
+
18
+ def id
19
+ "#{@name}_does_not_match"
20
+ end
21
+
22
+ def context
23
+ if @comparison.is_a?(Regexp)
24
+ {
25
+ "pattern" => @comparison
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module Shogun
2
+ module Verifier
3
+ class Presence
4
+ def initialize(name:, data:)
5
+ @data = data
6
+ @name = name
7
+ end
8
+
9
+ def valid?
10
+ if @data.is_a?(String)
11
+ @data.split("").any?
12
+ else
13
+ !@data.nil?
14
+ end
15
+ end
16
+
17
+ def id
18
+ "#{@name}_not_present"
19
+ end
20
+
21
+ def context
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module Shogun
2
+ module Verifier
3
+ class Range
4
+ def initialize(name:, data:, range:)
5
+ @data = data
6
+ @name = name
7
+ @range = range
8
+ end
9
+
10
+ def valid?
11
+ if @data.is_a?(String)
12
+ @range.cover?(@data.size)
13
+ else
14
+ @range.cover?(@data)
15
+ end
16
+ end
17
+
18
+ def id
19
+ "#{@name}_was_out_of_range"
20
+ end
21
+
22
+ def context
23
+ {
24
+ "maximum" => @range.max,
25
+ "minimum" => @range.min
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ module Shogun
2
+ module Verifier
3
+ class Uniqueness
4
+ def initialize(data:, name:, list: [])
5
+ @data = data
6
+ @name = name
7
+ @list = list || []
8
+ end
9
+
10
+ def valid?
11
+ !@list.include?(@data)
12
+ end
13
+
14
+ def id
15
+ "#{@name}_not_unique"
16
+ end
17
+
18
+ def context
19
+ nil
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Shogun
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Authorizer do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Control::Null do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Control do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Database do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Denormalizer do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Dispatch::Lookup do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Dispatch::Payload do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Dispatch::Route::Null do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Dispatch::Route do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Dispatch do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ describe Shogun::Endpoint do
4
+
5
+ end