roadforest 0.0.3 → 0.1
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.
- checksums.yaml +7 -0
- data/examples/file-management.rb +7 -9
- data/lib/roadforest/application/dispatcher.rb +44 -31
- data/lib/roadforest/application/parameters.rb +5 -4
- data/lib/roadforest/application/path-provider.rb +14 -1
- data/lib/roadforest/application/route-adapter.rb +15 -4
- data/lib/roadforest/application/services-host.rb +41 -7
- data/lib/roadforest/application.rb +4 -8
- data/lib/roadforest/authorization.rb +231 -0
- data/lib/roadforest/blob-model.rb +2 -11
- data/lib/roadforest/content-handling/engine.rb +12 -6
- data/lib/roadforest/content-handling/handler-wrap.rb +45 -0
- data/lib/roadforest/content-handling/media-type.rb +20 -12
- data/lib/roadforest/content-handling/type-handler.rb +76 -0
- data/lib/roadforest/content-handling/type-handlers/jsonld.rb +2 -146
- data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +38 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/document-environment.rb +34 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/object-environment.rb +62 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/property-environment.rb +46 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +574 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-environment.rb +144 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/subject-environment.rb +80 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer.rb +163 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa.rb +175 -0
- data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +297 -0
- data/lib/roadforest/debug.rb +10 -0
- data/lib/roadforest/http/graph-response.rb +3 -7
- data/lib/roadforest/http/graph-transfer.rb +28 -106
- data/lib/roadforest/http/keychain.rb +79 -0
- data/lib/roadforest/http/message.rb +9 -1
- data/lib/roadforest/http/user-agent.rb +115 -0
- data/lib/roadforest/http.rb +8 -0
- data/lib/roadforest/model.rb +48 -3
- data/lib/roadforest/rdf/graph-focus.rb +5 -3
- data/lib/roadforest/rdf/graph-store.rb +4 -2
- data/lib/roadforest/rdf/normalization.rb +6 -1
- data/lib/roadforest/remote-host.rb +22 -7
- data/lib/roadforest/resource/rdf/read-only.rb +15 -1
- data/lib/roadforest/templates/base/doc.haml +13 -0
- data/lib/roadforest/templates/base/property_value.haml +12 -0
- data/lib/roadforest/templates/base/property_values.haml +6 -0
- data/lib/roadforest/templates/base/subject.haml +4 -0
- data/lib/roadforest/templates/distiller/doc.haml +20 -0
- data/lib/roadforest/templates/distiller/nil-object.haml +1 -0
- data/lib/roadforest/templates/distiller/property_value.haml +7 -0
- data/lib/roadforest/templates/distiller/property_values.haml +7 -0
- data/lib/roadforest/templates/distiller/subject.haml +5 -0
- data/lib/roadforest/templates/min/doc.haml +10 -0
- data/lib/roadforest/templates/min/property_values.haml +7 -0
- data/lib/roadforest/templates/min/subject.haml +2 -0
- data/lib/roadforest/templates/nil-object.haml +0 -0
- data/lib/roadforest/templates/node-object.haml +1 -0
- data/lib/roadforest/templates/object.haml +1 -0
- data/lib/roadforest/templates/uri-object.haml +1 -0
- data/lib/roadforest/templates/xml-literal-object.haml +1 -0
- data/lib/roadforest/utility/class-registry.rb +4 -0
- data/spec/client.rb +119 -77
- data/spec/{excon-adapater.rb → excon-adapter.rb} +4 -0
- data/spec/full-integration.rb +6 -2
- data/spec/graph-store.rb +1 -1
- data/spec/media-types.rb +29 -2
- metadata +102 -125
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f4089bbfd4e58f956b5088ab646d62d904f11120
|
4
|
+
data.tar.gz: ebbccc85db766f417254b23aee95d022392e1b58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ecbf4fd992414ab2b73de911097455ef4712fbb9cb0c6f7bd7316a62abad9ca7b12ea5415b33817aaf9fc3bf83731500e684fe1099fa9ac217247ce94fe66883
|
7
|
+
data.tar.gz: 0a4125f562e7c390e5a515e4e06ba9099bd50268fa596734de825bce26c038d85c612594bc2b4db5ec521506430db1797e4ba3d3e772604f71de3c2a314d0c07
|
data/examples/file-management.rb
CHANGED
@@ -36,7 +36,7 @@ module FileManagementExample
|
|
36
36
|
def nav_entry(graph, name, path)
|
37
37
|
graph.add_node([:skos, :hasTopConcept], "#" + name) do |entry|
|
38
38
|
entry[:rdf, :type] = [:skos, "Concept"]
|
39
|
-
entry[:skos, :
|
39
|
+
entry[:skos, :prefLabel] = name
|
40
40
|
entry[:foaf, "page"] = path
|
41
41
|
end
|
42
42
|
end
|
@@ -65,13 +65,11 @@ module FileManagementExample
|
|
65
65
|
graph.add_list(:lc, "needs") do |list|
|
66
66
|
services.file_records.each do |record|
|
67
67
|
if !record.resolved
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# end
|
74
|
-
list << path_for(:need, '*' => record.name)
|
68
|
+
need = copy_model(graph, :need, '*' => [record.name])
|
69
|
+
need[:lc, :name]
|
70
|
+
need[:lc, :digest]
|
71
|
+
|
72
|
+
list.append(need.subject)
|
75
73
|
end
|
76
74
|
end
|
77
75
|
end
|
@@ -79,7 +77,7 @@ module FileManagementExample
|
|
79
77
|
end
|
80
78
|
|
81
79
|
class NeedContent < RoadForest::BlobModel
|
82
|
-
add_type "text/plain"
|
80
|
+
add_type TypeHandlers::Handler.new, "text/plain"
|
83
81
|
end
|
84
82
|
|
85
83
|
class Need < RoadForest::RDFModel
|
@@ -3,39 +3,16 @@ require 'roadforest/application/route-adapter'
|
|
3
3
|
|
4
4
|
module RoadForest
|
5
5
|
class Dispatcher < Webmachine::Dispatcher
|
6
|
-
def initialize(
|
6
|
+
def initialize(application)
|
7
7
|
super(method(:create_resource))
|
8
|
-
@
|
8
|
+
@application = application
|
9
9
|
@route_names = {}
|
10
10
|
@trace_by_default = false
|
11
11
|
end
|
12
|
-
attr_accessor :
|
12
|
+
attr_accessor :application, :trace_by_default
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def bundle_typed_resource(resource_type, model_class, route_name)
|
19
|
-
resource_class = Resource.get(resource_type)
|
20
|
-
bundle(resource_class) do |resource, request, response|
|
21
|
-
resource.model = model_class.new(route_name, resource.params, services)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def bundle_traced_resource(resource_type, model_class, route_name)
|
26
|
-
resource_class = Resource.get(resource_type)
|
27
|
-
bundle(resource_class) do |resource, request, response|
|
28
|
-
resource.model = model_class.new(route_name, resource.params, services)
|
29
|
-
resource.trace = true
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def resource_route(resource, name, path_spec, bindings)
|
34
|
-
route = Route.new(path_spec, resource, bindings || {})
|
35
|
-
yield route if block_given?
|
36
|
-
@route_names[name] = route
|
37
|
-
@routes << route
|
38
|
-
route
|
14
|
+
def route_for_name(name)
|
15
|
+
@route_names.fetch(name)
|
39
16
|
end
|
40
17
|
|
41
18
|
def add_route(name, path_spec, resource_type, model_class, bindings = nil, &block)
|
@@ -59,8 +36,27 @@ module RoadForest
|
|
59
36
|
end
|
60
37
|
alias add_traced add_traced_route
|
61
38
|
|
62
|
-
def
|
63
|
-
|
39
|
+
def resource_route(resource, name, path_spec, bindings)
|
40
|
+
route = Route.new(path_spec, resource, bindings || {})
|
41
|
+
yield route if block_given?
|
42
|
+
@route_names[name] = route
|
43
|
+
@routes << route
|
44
|
+
route
|
45
|
+
end
|
46
|
+
|
47
|
+
def bundle_typed_resource(resource_type, model_class, route_name)
|
48
|
+
resource_class = Resource.get(resource_type)
|
49
|
+
Application::RouteAdapter.new(route_name, resource_class, model_class) do |adapter|
|
50
|
+
adapter.application = application
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def bundle_traced_resource(resource_type, model_class, route_name)
|
55
|
+
resource_class = Resource.get(resource_type)
|
56
|
+
Application::RouteAdapter.new(route_name, resource_class, model_class) do |adapter|
|
57
|
+
adapter.application = application
|
58
|
+
adapter.trace = true
|
59
|
+
end
|
64
60
|
end
|
65
61
|
|
66
62
|
class Route < Webmachine::Dispatcher::Route
|
@@ -68,7 +64,8 @@ module RoadForest
|
|
68
64
|
# substitution.
|
69
65
|
# @param [Hash] vars values for the path variables
|
70
66
|
# @return [String] the valid URL for the route
|
71
|
-
def build_path(vars =
|
67
|
+
def build_path(vars = nil)
|
68
|
+
vars ||= {}
|
72
69
|
"/" + path_spec.map do |segment|
|
73
70
|
case segment
|
74
71
|
when '*',Symbol
|
@@ -78,6 +75,22 @@ module RoadForest
|
|
78
75
|
end
|
79
76
|
end.join("/")
|
80
77
|
end
|
78
|
+
|
79
|
+
def build_params(vars = nil)
|
80
|
+
vars ||= {}
|
81
|
+
params = Application::Parameters.new
|
82
|
+
path_set = Hash[path_spec.find_all{|segment| segment.is_a? Symbol}.map{|seg| [seg, true]}]
|
83
|
+
vars.to_hash.each do |key, value|
|
84
|
+
if(path_set.has_key?(key))
|
85
|
+
params.path_info[key] = value
|
86
|
+
elsif(key == '*')
|
87
|
+
params.path_tokens = value
|
88
|
+
else
|
89
|
+
params.query_params[key] = value
|
90
|
+
end
|
91
|
+
end
|
92
|
+
params
|
93
|
+
end
|
81
94
|
end
|
82
95
|
end
|
83
96
|
end
|
@@ -12,13 +12,14 @@ module RoadForest
|
|
12
12
|
attr_accessor :path_info, :query_params, :path_tokens
|
13
13
|
|
14
14
|
def [](field_name)
|
15
|
-
|
16
|
-
|
15
|
+
fetch(field_name)
|
16
|
+
rescue KeyError
|
17
|
+
nil
|
17
18
|
end
|
18
19
|
|
19
20
|
def fetch(field_name)
|
20
|
-
return path_tokens if
|
21
|
-
@path_info
|
21
|
+
return path_tokens if field_name == '*'
|
22
|
+
@path_info.fetch(field_name){ @query_params.fetch(field_name) }
|
22
23
|
end
|
23
24
|
|
24
25
|
def slice(*fields)
|
@@ -10,9 +10,22 @@ module RoadForest
|
|
10
10
|
# @param [Hash] vars the values for the required path variables
|
11
11
|
# @raise [RuntimeError] Raised if the resource is not routable.
|
12
12
|
# @return [String] the URL
|
13
|
-
def path_for(name, vars =
|
13
|
+
def path_for(name, vars = nil)
|
14
|
+
vars ||= {}
|
14
15
|
route = @dispatcher.route_for_name(name)
|
15
16
|
::RDF::URI.parse(route.build_path(vars))
|
16
17
|
end
|
18
|
+
|
19
|
+
def request_for(name, vars = nil)
|
20
|
+
url = path_for(name, vars) #full url?
|
21
|
+
|
22
|
+
Webmachine::Request.new(method, url, headers, body)
|
23
|
+
end
|
24
|
+
|
25
|
+
def model_for(name, vars = nil)
|
26
|
+
route = @dispatcher.route_for_name(name)
|
27
|
+
params = route.build_params(vars)
|
28
|
+
route.resource.build_model(params)
|
29
|
+
end
|
17
30
|
end
|
18
31
|
end
|
@@ -1,17 +1,28 @@
|
|
1
1
|
module RoadForest
|
2
2
|
class Application
|
3
3
|
class RouteAdapter
|
4
|
-
def initialize(resource_class,
|
4
|
+
def initialize(route_name, resource_class, model_class)
|
5
5
|
@resource_class = resource_class
|
6
|
-
|
6
|
+
|
7
|
+
@route_name = route_name
|
8
|
+
@model_class = model_class
|
9
|
+
@application = nil
|
10
|
+
@trace = false
|
11
|
+
yield self if block_given?
|
7
12
|
end
|
13
|
+
attr_accessor :route_name, :resource_class, :model_class, :application, :trace
|
8
14
|
|
9
15
|
def new(request, response)
|
10
|
-
resource =
|
11
|
-
|
16
|
+
resource = resource_class.new(request, response)
|
17
|
+
resource.model = build_model(resource.params)
|
18
|
+
resource.trace = trace
|
12
19
|
resource
|
13
20
|
end
|
14
21
|
|
22
|
+
def build_model(params)
|
23
|
+
model_class.new(route_name, params, application.services)
|
24
|
+
end
|
25
|
+
|
15
26
|
def <(klass)
|
16
27
|
if klass <= Webmachine::Resource
|
17
28
|
return true
|
@@ -1,10 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module RoadForest
|
2
|
+
class Application
|
3
|
+
#XXX Worth doing some meta to get reality checking of configs here? Better
|
4
|
+
#fail early if there's no DB configured, right?
|
5
|
+
class ServicesHost
|
6
|
+
def initialize
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_writer :application
|
10
|
+
attr_writer :router, :canonical_host, :type_handling
|
11
|
+
attr_writer :logger, :authorization
|
12
|
+
|
13
|
+
def canonical_host
|
14
|
+
@application.canonical_host
|
15
|
+
end
|
16
|
+
|
17
|
+
def router
|
18
|
+
@router ||= PathProvider.new(@application.dispatcher)
|
19
|
+
end
|
7
20
|
|
8
|
-
|
21
|
+
def authorization
|
22
|
+
@authorization ||=
|
23
|
+
begin
|
24
|
+
require 'roadforest/authorization'
|
25
|
+
Authorization::Manager.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def type_handling
|
30
|
+
@type_handling ||= ContentHandling::Engine.default
|
31
|
+
end
|
32
|
+
|
33
|
+
def logger
|
34
|
+
@logger ||=
|
35
|
+
begin
|
36
|
+
require 'logger'
|
37
|
+
Logger.new("roadforest.log")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
alias authz authorization
|
42
|
+
end
|
9
43
|
end
|
10
44
|
end
|
@@ -9,6 +9,7 @@ require 'roadforest/application/services-host'
|
|
9
9
|
require 'roadforest/resource/rdf'
|
10
10
|
require 'roadforest/content-handling/engine'
|
11
11
|
require 'roadforest/rdf/normalization'
|
12
|
+
require 'roadforest/authorization'
|
12
13
|
|
13
14
|
module RoadForest
|
14
15
|
class Application
|
@@ -17,7 +18,7 @@ module RoadForest
|
|
17
18
|
def initialize(canonical_host, services = nil, configuration = nil, dispatcher = nil)
|
18
19
|
@canonical_host = normalize_resource(canonical_host)
|
19
20
|
configuration ||= Webmachine::Configuration.default
|
20
|
-
dispatcher ||= Dispatcher.new(
|
21
|
+
dispatcher ||= Dispatcher.new(self)
|
21
22
|
super(configuration, dispatcher)
|
22
23
|
self.services = services unless services.nil?
|
23
24
|
|
@@ -31,17 +32,12 @@ module RoadForest
|
|
31
32
|
|
32
33
|
alias router dispatcher
|
33
34
|
|
35
|
+
#XXX Is this the right place for this?
|
34
36
|
def services=(service_host)
|
35
|
-
router.services = service_host
|
36
37
|
@services = service_host
|
38
|
+
service_host.application = self
|
37
39
|
@services.canonical_host = canonical_host
|
38
40
|
@services.router = PathProvider.new(@dispatcher)
|
39
|
-
@services.type_handling ||= ContentHandling::Engine.default
|
40
|
-
@services.logger ||=
|
41
|
-
begin
|
42
|
-
require 'logger'
|
43
|
-
Logger.new("roadforest.log")
|
44
|
-
end
|
45
41
|
end
|
46
42
|
end
|
47
43
|
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'openssl'
|
3
|
+
require 'roadforest'
|
4
|
+
require 'roadforest/utility/class-registry'
|
5
|
+
|
6
|
+
module RoadForest
|
7
|
+
module Authorization
|
8
|
+
class GrantBuilder
|
9
|
+
def initialize(salt, cache)
|
10
|
+
@salt = salt
|
11
|
+
@cache = cache
|
12
|
+
@list = []
|
13
|
+
end
|
14
|
+
attr_reader :list
|
15
|
+
|
16
|
+
def add(name, params=nil)
|
17
|
+
canonical =
|
18
|
+
if params.nil?
|
19
|
+
[@salt, name]
|
20
|
+
else
|
21
|
+
[@salt, name, params.keys.sort.map do |key|
|
22
|
+
[key, params[key]]
|
23
|
+
end]
|
24
|
+
end
|
25
|
+
@list << @cache[canonical]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class GrantsHolder
|
30
|
+
def initialize(salt, hash_function)
|
31
|
+
@salt = salt
|
32
|
+
|
33
|
+
digester = OpenSSL::Digest.new(hash_function)
|
34
|
+
@grants_cache = Hash.new do |h, k| #XXX potential resource exhaustion here - only accumulate auth'd results
|
35
|
+
digester.reset
|
36
|
+
h[k] = digester.digest(h.inspect)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def get(key)
|
41
|
+
@grants_cache[key]
|
42
|
+
end
|
43
|
+
alias [] get
|
44
|
+
|
45
|
+
def build_grants
|
46
|
+
builder = GrantBuilder.new(@salt, self)
|
47
|
+
yield builder
|
48
|
+
return builder.list
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Manager
|
53
|
+
attr_accessor :authenticator
|
54
|
+
attr_accessor :policy
|
55
|
+
attr_reader :grants
|
56
|
+
|
57
|
+
HASH_FUNCTION = "SHA256".freeze
|
58
|
+
|
59
|
+
def initialize(salt = nil, authenticator = nil, policy = nil)
|
60
|
+
@grants = GrantsHolder.new(salt || "roadforest-insecure", HASH_FUNCTION)
|
61
|
+
|
62
|
+
@authenticator = authenticator || AuthenticationChain.new(DefaultAuthenticationStore.new)
|
63
|
+
@policy = policy || AuthorizationPolicy.new
|
64
|
+
@policy.grants_holder = @grants
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_grants(&block)
|
68
|
+
@grants.build_grants(&block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def challenge(options)
|
72
|
+
@authenticator.challenge(options)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @returns [:public|:granted|:refused]
|
76
|
+
#
|
77
|
+
# :public means the request doesn't need authorization
|
78
|
+
# :granted means that it does need authz but the credentials passed are
|
79
|
+
# allowed to access the resource
|
80
|
+
# :refused means that the credentials passed are not allowed to access
|
81
|
+
# the resource
|
82
|
+
#
|
83
|
+
# TODO: Resource needs to add s-maxage=0 for :granted requests or public
|
84
|
+
# for :public requests to the CacheControl header
|
85
|
+
def authorization(header, required_grants)
|
86
|
+
entity = authenticator.authenticate(header)
|
87
|
+
|
88
|
+
return :refused if entity.nil?
|
89
|
+
|
90
|
+
available_grants = policy.grants_for(entity)
|
91
|
+
|
92
|
+
if required_grants.any?{|required| available_grants.include?(required)}
|
93
|
+
return :granted
|
94
|
+
else
|
95
|
+
return :refused
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class AuthenticationChain
|
101
|
+
class Scheme
|
102
|
+
def self.registry_purpose; "authentication scheme"; end
|
103
|
+
extend Utility::ClassRegistry::Registrar
|
104
|
+
|
105
|
+
def self.register(name)
|
106
|
+
registrar.registry.add(name, self.new)
|
107
|
+
end
|
108
|
+
|
109
|
+
def authenticated_entity(credentials, store)
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class Basic < Scheme
|
115
|
+
register "Basic"
|
116
|
+
|
117
|
+
def challenge(options)
|
118
|
+
"Basic realm=\"#{options.fetch(:realm, "Roadforest App")}\""
|
119
|
+
end
|
120
|
+
|
121
|
+
def authenticated_entity(credentials, store)
|
122
|
+
username, password = Base64.decode64(credentials).split(':',2)
|
123
|
+
|
124
|
+
entity = store.by_username(username)
|
125
|
+
entity.authenticate_by_password(password)
|
126
|
+
entity
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def initialize(store)
|
131
|
+
@store = store
|
132
|
+
end
|
133
|
+
attr_reader :store
|
134
|
+
|
135
|
+
def handler_for(scheme)
|
136
|
+
Scheme.get(scheme)
|
137
|
+
rescue
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
|
141
|
+
def challenge(options)
|
142
|
+
(Scheme.registry.names.map do |scheme_name|
|
143
|
+
handler_for(scheme_name).challenge(options)
|
144
|
+
end).join(", ")
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_account(user,password,token)
|
148
|
+
@store.add_account(user,password,token)
|
149
|
+
end
|
150
|
+
|
151
|
+
def authenticate(header)
|
152
|
+
return nil if header.nil?
|
153
|
+
scheme, credentials = header.split(/\s+/, 2)
|
154
|
+
|
155
|
+
handler = handler_for(scheme)
|
156
|
+
return nil if handler.nil?
|
157
|
+
|
158
|
+
entity = handler.authenticated_entity(credentials, store)
|
159
|
+
return nil if entity.nil?
|
160
|
+
return nil unless entity.authenticated?
|
161
|
+
return entity
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class AuthEntity
|
166
|
+
def initialize
|
167
|
+
@authenticated = false
|
168
|
+
end
|
169
|
+
attr_accessor :username, :password, :token
|
170
|
+
|
171
|
+
def authenticated?
|
172
|
+
!!@authenticated
|
173
|
+
end
|
174
|
+
|
175
|
+
def authenticate_by_password(password)
|
176
|
+
@authenticated = (!password.nil? and password == @password)
|
177
|
+
end
|
178
|
+
|
179
|
+
def authenticate_by_token(token)
|
180
|
+
@authenticated = (!token.nil? and token == @token)
|
181
|
+
end
|
182
|
+
|
183
|
+
def authenticate!
|
184
|
+
@authenticated = true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
class DefaultAuthenticationStore
|
189
|
+
def initialize
|
190
|
+
@accounts = []
|
191
|
+
end
|
192
|
+
|
193
|
+
def build_entity(account)
|
194
|
+
return nil if account.nil?
|
195
|
+
AuthEntity.new.tap do |entity|
|
196
|
+
entity.username = account[0]
|
197
|
+
entity.password = account[1]
|
198
|
+
entity.token = account[2]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def add_account(user, password, token)
|
203
|
+
@accounts << [user, password, token]
|
204
|
+
end
|
205
|
+
|
206
|
+
def by_username(username)
|
207
|
+
account = @accounts.find{|account| account[0] == username }
|
208
|
+
build_entity(account)
|
209
|
+
end
|
210
|
+
|
211
|
+
def by_token(token)
|
212
|
+
account = @accounts.find{|account| account[2] == token }
|
213
|
+
build_entity(account)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class AuthorizationPolicy
|
218
|
+
attr_accessor :grants_holder
|
219
|
+
|
220
|
+
def build_grants(&block)
|
221
|
+
grants_holder.build_grants(&block)
|
222
|
+
end
|
223
|
+
|
224
|
+
def grants_for(entity)
|
225
|
+
build_grants do |builder|
|
226
|
+
builder.add(:admin)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
@@ -9,19 +9,10 @@ module RoadForest
|
|
9
9
|
@engine ||= ContentHandling::Engine.new
|
10
10
|
end
|
11
11
|
|
12
|
-
def add_type(
|
13
|
-
|
14
|
-
add_renderer(type, handler)
|
12
|
+
def add_type(handler, type)
|
13
|
+
type_handling.add_type(handler, type)
|
15
14
|
end
|
16
15
|
alias add add_type
|
17
|
-
|
18
|
-
def add_parser(type, handler)
|
19
|
-
type_handling.add_parser(type, handler)
|
20
|
-
end
|
21
|
-
|
22
|
-
def add_renderer(type, handler)
|
23
|
-
type_handling.add_renderer(type, handler)
|
24
|
-
end
|
25
16
|
end
|
26
17
|
|
27
18
|
def type_handling
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'roadforest/content-handling/media-type'
|
2
|
+
require 'roadforest/content-handling/handler-wrap'
|
2
3
|
|
3
4
|
module RoadForest
|
4
5
|
module ContentHandling
|
@@ -47,8 +48,13 @@ module RoadForest
|
|
47
48
|
|
48
49
|
def self.default
|
49
50
|
require 'roadforest/content-handling/type-handlers/jsonld'
|
51
|
+
require 'roadforest/content-handling/type-handlers/rdfa'
|
50
52
|
self.new.tap do |engine|
|
51
|
-
engine.add
|
53
|
+
engine.add RoadForest::MediaType::Handlers::RDFa.new, "text/html;q=1;rdfa=1"
|
54
|
+
engine.add RoadForest::MediaType::Handlers::RDFa.new, "application/xhtml+xml;q=1;rdfa=1"
|
55
|
+
engine.add RoadForest::MediaType::Handlers::JSONLD.new, "application/ld+json"
|
56
|
+
engine.add RoadForest::MediaType::Handlers::RDFa.new, "text/html;q=0.5"
|
57
|
+
engine.add RoadForest::MediaType::Handlers::RDFa.new, "application/xhtml+xml;q=0.5"
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
@@ -59,21 +65,21 @@ module RoadForest
|
|
59
65
|
end
|
60
66
|
attr_reader :renderers, :parsers
|
61
67
|
|
62
|
-
def add_type(
|
68
|
+
def add_type(handler, type)
|
63
69
|
type = MediaType.parse(type)
|
64
|
-
add_parser(
|
65
|
-
add_renderer(
|
70
|
+
add_parser(handler, type)
|
71
|
+
add_renderer(handler, type)
|
66
72
|
end
|
67
73
|
alias add add_type
|
68
74
|
|
69
|
-
def add_parser(
|
75
|
+
def add_parser(object, type)
|
70
76
|
type = MediaType.parse(type)
|
71
77
|
wrapper = RoadForest::MediaType::Handlers::Wrap::Parse.new(type, object)
|
72
78
|
parsers.add(wrapper)
|
73
79
|
end
|
74
80
|
alias accept add_parser
|
75
81
|
|
76
|
-
def add_renderer(
|
82
|
+
def add_renderer(object, type)
|
77
83
|
type = MediaType.parse(type)
|
78
84
|
wrapper = RoadForest::MediaType::Handlers::Wrap::Render.new(type, object)
|
79
85
|
renderers.add(wrapper)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RoadForest
|
2
|
+
module MediaType
|
3
|
+
module Handlers
|
4
|
+
module Wrap
|
5
|
+
class Wrapper
|
6
|
+
def initialize(type, handler)
|
7
|
+
@type = type
|
8
|
+
@handler = handler
|
9
|
+
end
|
10
|
+
attr_reader :type, :handler
|
11
|
+
|
12
|
+
def local_to_network(base_uri, network)
|
13
|
+
@handler.local_to_network(base_uri, network)
|
14
|
+
end
|
15
|
+
alias from_graph local_to_network
|
16
|
+
|
17
|
+
def network_to_local(base_uri, source)
|
18
|
+
@handler.network_to_local(base_uri, source)
|
19
|
+
end
|
20
|
+
alias to_graph network_to_local
|
21
|
+
end
|
22
|
+
|
23
|
+
class Render < Wrapper
|
24
|
+
def call(resource)
|
25
|
+
@handler.render_for(resource)
|
26
|
+
end
|
27
|
+
|
28
|
+
def content_type_header
|
29
|
+
@type.content_type_header
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Parse < Wrapper
|
34
|
+
def call(resource)
|
35
|
+
@handler.parse_for(resource)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_child(resource)
|
39
|
+
@handler.add_child_to(resource)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|