shogun 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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