psc 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/.rvmrc +2 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +20 -0
- data/LICENSE +20 -0
- data/README.md +163 -0
- data/Rakefile +69 -0
- data/cucumber.yml +13 -0
- data/features/step_definitions/eval_steps.rb +14 -0
- data/features/step_definitions/setup_steps.rb +7 -0
- data/features/studies.feature +21 -0
- data/features/support/env.rb +33 -0
- data/features/support/int_psc.rb +165 -0
- data/int-psc/README-int-psc.md +57 -0
- data/int-psc/hsqldb/baseline.log +197 -0
- data/int-psc/hsqldb/baseline.properties +17 -0
- data/int-psc/hsqldb/baseline.script +295 -0
- data/int-psc/hsqldb/datasource.properties +18 -0
- data/int-psc/hsqldb/datasource.script +2205 -0
- data/int-psc/jetty/jetty-runner-7.4.0.v20110414.jar +0 -0
- data/int-psc/state/ABC 1200.xml +115 -0
- data/int-psc/state/int-psc-state.xml +64 -0
- data/lib/psc.rb +47 -0
- data/lib/psc/client.rb +35 -0
- data/lib/psc/connection.rb +96 -0
- data/lib/psc/faraday.rb +11 -0
- data/lib/psc/faraday/http_basic.rb +35 -0
- data/lib/psc/faraday/psc_token.rb +42 -0
- data/lib/psc/faraday/string_is_xml.rb +25 -0
- data/lib/psc/version.rb +3 -0
- data/meta.rakefile +30 -0
- data/psc.gemspec +33 -0
- data/spec/fixtures/studies-json.http +37 -0
- data/spec/middleware_helper.rb +18 -0
- data/spec/psc/client_spec.rb +39 -0
- data/spec/psc/connection_spec.rb +156 -0
- data/spec/psc/faraday/http_basic_spec.rb +15 -0
- data/spec/psc/faraday/psc_token_spec.rb +38 -0
- data/spec/psc/faraday/string_is_xml_spec.rb +49 -0
- data/spec/psc/version_spec.rb +11 -0
- data/spec/psc_spec.rb +16 -0
- data/spec/spec_helper.rb +15 -0
- data/tasks/int-psc.rake +84 -0
- data/tasks/psc/TODO +3 -0
- data/tasks/psc/state.rb +393 -0
- metadata +311 -0
Binary file
|
@@ -0,0 +1,115 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
|
3
|
+
<study xmlns="http://bioinformatics.northwestern.edu/ns/psc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" assigned-identifier="ABC 1200" last-modified-date="2011-05-12T11:10:29.740Z" xsi:schemaLocation="http://bioinformatics.northwestern.edu/ns/psc http://bioinformatics.northwestern.edu/ns/psc/psc.xsd">
|
4
|
+
<planned-calendar id="9c9c8042-75f1-477a-8855-40e6084f0954"/>
|
5
|
+
<amendment name="[Original]" date="2011-05-12" mandatory="true" released-date="2011-05-12T11:10:29.740Z" updated-date="2011-05-12T10:44:34.568Z">
|
6
|
+
<planned-calendar-delta id="d7adaa30-e2f0-4415-a751-53ccee9433ca" node-id="9c9c8042-75f1-477a-8855-40e6084f0954">
|
7
|
+
<add id="234ae5fa-e712-473d-b395-7e5edf9ef532" index="0">
|
8
|
+
<epoch id="72e7e90a-5f09-49b7-9dc4-785d56cf4414" name="Treatment">
|
9
|
+
<study-segment id="f174f7c2-ceed-4c6c-8392-1688f34b7905" name="A">
|
10
|
+
<period id="e74bbe38-46ad-410c-acd8-fb70f9527c0b" name="Surgery" repetitions="1" start-day="1" duration-quantity="1" duration-unit="day">
|
11
|
+
<planned-activity id="db2ffa63-8c28-43cd-94c4-e8f6801ce42b" day="1">
|
12
|
+
<activity-reference code="1041" source="Northwestern University"/>
|
13
|
+
</planned-activity>
|
14
|
+
</period>
|
15
|
+
<period id="1d8227b3-8f40-424c-a238-bffcda982014" name="Frequent monitoring" repetitions="24" start-day="1" duration-quantity="1" duration-unit="week">
|
16
|
+
<planned-activity id="2da856a4-3d40-4d04-8804-c9ee2b9f90b3" day="1">
|
17
|
+
<activity-reference code="360" source="Northwestern University"/>
|
18
|
+
</planned-activity>
|
19
|
+
<planned-activity id="09791bfb-eaf6-418a-8516-fae296df23f0" day="1">
|
20
|
+
<activity-reference code="253" source="Northwestern University"/>
|
21
|
+
</planned-activity>
|
22
|
+
</period>
|
23
|
+
<period id="e93b9f37-43de-4873-a776-1e7fcefbec59" name="Infrequent monitoring" repetitions="6" start-day="1" duration-quantity="1" duration-unit="month">
|
24
|
+
<planned-activity id="3ad03935-5bdf-448e-88ee-ee656d12afe3" day="1">
|
25
|
+
<activity-reference code="701" source="Northwestern University"/>
|
26
|
+
</planned-activity>
|
27
|
+
<planned-activity id="6fdbfd73-6cc3-41a6-a388-b19cf2bf7b25" day="1">
|
28
|
+
<activity-reference code="451" source="Northwestern University"/>
|
29
|
+
</planned-activity>
|
30
|
+
</period>
|
31
|
+
<period id="0c7852e2-eca1-4b57-9e7a-2d222abf43ea" name="Intervention" repetitions="8" start-day="8" duration-quantity="3" duration-unit="week">
|
32
|
+
<planned-activity id="845b63f0-389d-4b7c-b9df-986b7dd3e4ad" day="1">
|
33
|
+
<activity-reference code="211" source="Northwestern University"/>
|
34
|
+
</planned-activity>
|
35
|
+
<planned-activity id="0be23936-1621-49b3-862e-90eee0b03bf4" day="15">
|
36
|
+
<activity-reference code="211" source="Northwestern University"/>
|
37
|
+
</planned-activity>
|
38
|
+
<planned-activity id="7f599ee3-f45f-4af1-bcfd-3d377b3bbc4a" day="8">
|
39
|
+
<activity-reference code="43" source="Northwestern University"/>
|
40
|
+
</planned-activity>
|
41
|
+
</period>
|
42
|
+
</study-segment>
|
43
|
+
<study-segment id="fe329f59-1253-405a-9933-ea2d70bdf0dc" name="B">
|
44
|
+
<period id="538baa4e-6e4f-4e67-a112-b5a5d1200ba9" name="Frequent monitoring" repetitions="24" start-day="1" duration-quantity="1" duration-unit="week">
|
45
|
+
<planned-activity id="e742696d-c066-4e59-9bd2-f064a468ca87" day="1">
|
46
|
+
<activity-reference code="360" source="Northwestern University"/>
|
47
|
+
</planned-activity>
|
48
|
+
<planned-activity id="d882f175-13ae-4c16-9aa2-38f27c2ea2a6" day="1">
|
49
|
+
<activity-reference code="253" source="Northwestern University"/>
|
50
|
+
</planned-activity>
|
51
|
+
</period>
|
52
|
+
<period id="d54584c4-acc5-4de9-8323-ed36cbced4bc" name="Infrequent monitoring" repetitions="6" start-day="1" duration-quantity="1" duration-unit="month">
|
53
|
+
<planned-activity id="b23569f5-1268-4264-8c4d-bae166616d16" day="1">
|
54
|
+
<activity-reference code="701" source="Northwestern University"/>
|
55
|
+
</planned-activity>
|
56
|
+
<planned-activity id="3c54d7b4-f2ec-4b9e-9fe4-b6d13b92aeba" day="1">
|
57
|
+
<activity-reference code="451" source="Northwestern University"/>
|
58
|
+
</planned-activity>
|
59
|
+
</period>
|
60
|
+
<period id="b85661ef-ff19-462f-83a4-3e53ed69cd84" name="Intervention" repetitions="8" start-day="8" duration-quantity="3" duration-unit="week">
|
61
|
+
<planned-activity id="23a0aac4-87f6-4cd3-8df1-71bee82505ae" day="1">
|
62
|
+
<activity-reference code="211" source="Northwestern University"/>
|
63
|
+
</planned-activity>
|
64
|
+
<planned-activity id="24deeecc-cba8-4d8c-bc55-35048970bb8e" day="15">
|
65
|
+
<activity-reference code="211" source="Northwestern University"/>
|
66
|
+
</planned-activity>
|
67
|
+
<planned-activity id="40cce9be-3a32-4477-9c8d-79104b8625f0" day="8">
|
68
|
+
<activity-reference code="43" source="Northwestern University"/>
|
69
|
+
</planned-activity>
|
70
|
+
</period>
|
71
|
+
</study-segment>
|
72
|
+
</epoch>
|
73
|
+
</add>
|
74
|
+
<add id="1b02eb68-d1c8-4d11-88f2-4785ff91f0bb" index="1">
|
75
|
+
<epoch id="1d0d08cc-ed40-4ebb-923f-ebe0c29e814d" name="Follow up">
|
76
|
+
<study-segment id="4c01e031-1fe9-41ad-970c-368cb57c0c8e" name="Follow up">
|
77
|
+
<period id="3b8bff21-4d30-475f-a9b7-a39afed63b94" name="QoL" repetitions="18" start-day="1" duration-quantity="1" duration-unit="quarter">
|
78
|
+
<planned-activity id="a33a6a83-2b27-4678-a395-4025b399882b" details="Administer by phone" day="1">
|
79
|
+
<activity-reference code="941" source="Northwestern University"/>
|
80
|
+
</planned-activity>
|
81
|
+
</period>
|
82
|
+
</study-segment>
|
83
|
+
</epoch>
|
84
|
+
</add>
|
85
|
+
<add id="aefbcdc5-ac5b-4c0d-b092-b6e9e337969e" index="2">
|
86
|
+
<epoch id="9d7bf8eb-6413-4286-97c0-f44f489883e6" name="Run-in">
|
87
|
+
<study-segment id="14969b7b-e49e-48e0-b081-ba94d9448479" name="Run-in">
|
88
|
+
<period id="3970c8a8-89e3-4d7e-98ac-4f27232cc624" repetitions="3" start-day="1" duration-quantity="7" duration-unit="day">
|
89
|
+
<planned-activity id="cdd73e03-1410-4ae6-9d86-4a8929cd1678" day="1">
|
90
|
+
<activity-reference code="360" source="Northwestern University"/>
|
91
|
+
</planned-activity>
|
92
|
+
<planned-activity id="0df8ccf3-2067-47c6-bbf3-dfbf8512968e" day="7">
|
93
|
+
<activity-reference code="593" source="Northwestern University"/>
|
94
|
+
</planned-activity>
|
95
|
+
</period>
|
96
|
+
</study-segment>
|
97
|
+
</epoch>
|
98
|
+
</add>
|
99
|
+
<reorder id="a455e585-1bee-4770-b191-63fb8ec70066" child-id="9d7bf8eb-6413-4286-97c0-f44f489883e6" old-index="2" new-index="0"/>
|
100
|
+
</planned-calendar-delta>
|
101
|
+
</amendment>
|
102
|
+
<sources>
|
103
|
+
<source name="Northwestern University">
|
104
|
+
<activity name="Ketones (Acetone)" code="593" type="Lab Test"/>
|
105
|
+
<activity name="Taxol" code="211" type="Intervention"/>
|
106
|
+
<activity name="Dialysis Chemistry Panel" code="451" type="Lab Test"/>
|
107
|
+
<activity name="24 hr urine, protein electrophoresis" code="253" type="Lab Test"/>
|
108
|
+
<activity name="Carboplatin" code="43" type="Intervention"/>
|
109
|
+
<activity name="Pregnancy Test" code="701" type="Lab Test"/>
|
110
|
+
<activity name="CBC" code="360" type="Lab Test"/>
|
111
|
+
<activity name="QOL Survey" code="941" type="Other"/>
|
112
|
+
<activity name="Surgery" code="1041" type="Procedure"/>
|
113
|
+
</source>
|
114
|
+
</sources>
|
115
|
+
</study>
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<!-- To rebuild the integration test PSC when you change this data, run `rake int-psc:rebuild` -->
|
2
|
+
|
3
|
+
<psc-state>
|
4
|
+
<!--
|
5
|
+
General note: Anywhere a date is specified, the value may either
|
6
|
+
be a date string in the form yyyy-mm-dd or an integer. An
|
7
|
+
integer indicates a date relative to today (negative, before
|
8
|
+
today; positive, after today).
|
9
|
+
-->
|
10
|
+
|
11
|
+
<site name="Northwestern University" assigned-identifier="IL036"/>
|
12
|
+
<site name="Mayo Clinic Rochester" assigned-identifier="MN026"/>
|
13
|
+
<site name="Thomas Jefferson University" assigned-identifier="PA121"/>
|
14
|
+
|
15
|
+
<!--
|
16
|
+
The assigned-identifier attribute for template is mandatory;
|
17
|
+
file is optional. If the file is omitted, it is assumed to be a
|
18
|
+
file named [assigned-identifier].xml in the same directory as
|
19
|
+
this state XML file.
|
20
|
+
-->
|
21
|
+
<template assigned-identifier="ABC 1200">
|
22
|
+
<!--
|
23
|
+
approval indicates whether the template should be marked as
|
24
|
+
approved for use by the site. It can be either a date or
|
25
|
+
false; the default is 0 (i.e., today). All released amendments
|
26
|
+
will have the same approval status.
|
27
|
+
-->
|
28
|
+
<participating-site assigned-identifier="IL036" approval="2008-01-07"/>
|
29
|
+
<participating-site assigned-identifier="PA121" approval="2010-01-02"/>
|
30
|
+
</template>
|
31
|
+
|
32
|
+
|
33
|
+
<registration>
|
34
|
+
<subject
|
35
|
+
first-name="Jo"
|
36
|
+
last-name="Fredricksson"
|
37
|
+
gender="Female"
|
38
|
+
birth-date="1950-06-01"
|
39
|
+
person-id="XC56700077"
|
40
|
+
>
|
41
|
+
<subject-property name="Hat size" value="7"/>
|
42
|
+
</subject>
|
43
|
+
<!-- template-identifier and site-identifier are mandatory attributes -->
|
44
|
+
<study-site
|
45
|
+
template="ABC 1200"
|
46
|
+
site="IL036"
|
47
|
+
study-subject-identifier="A0001"
|
48
|
+
desired-assignment-identifier="POP-2702">
|
49
|
+
<!--
|
50
|
+
* segment is either the ID for the segment or its "epoch: segment" name (mandatory).
|
51
|
+
* start is the start date for the segment (default: 0 for the first segment;
|
52
|
+
the end of the previous for subsequent). [TODO: the second part isn't implemented yet]
|
53
|
+
* mode is the transition mode for the segment (default: per-protocol).
|
54
|
+
-->
|
55
|
+
<scheduled-segment segment="Run-in" start="2010-01-01"/>
|
56
|
+
<scheduled-segment segment="Treatment: A" start="2010-02-01" mode="per-protocol"/>
|
57
|
+
<scheduled-segment segment="Follow up" start="2010-03-15" mode="immediate"/>
|
58
|
+
</study-site>
|
59
|
+
|
60
|
+
<!-- multiple study-sites allowed per registration to reuse the same subject -->
|
61
|
+
</registration>
|
62
|
+
|
63
|
+
<!-- multiple registrations allowed -->
|
64
|
+
</psc-state>
|
data/lib/psc.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
##
|
4
|
+
# The namespace for `psc.rb`.
|
5
|
+
module Psc
|
6
|
+
autoload :Faraday, 'psc/faraday'
|
7
|
+
autoload :Client, 'psc/client'
|
8
|
+
autoload :Connection, 'psc/connection'
|
9
|
+
|
10
|
+
##
|
11
|
+
# Wraps `Builder::XmlMarkup` to ease the construction of PSC XML
|
12
|
+
# entities. For example:
|
13
|
+
#
|
14
|
+
# Psc.xml('study-snapshot', :assigned_identifier => 'YUV 1234') do |snap|
|
15
|
+
# snap.tag!('long-title', 'Why you validly counting?')
|
16
|
+
# snap.tag!('planned-calendar') { |pc|
|
17
|
+
# pc.epoch(:name => 'Run-in') { |e|
|
18
|
+
# # and so on
|
19
|
+
# }
|
20
|
+
# }
|
21
|
+
# snap.sources { |sources|
|
22
|
+
# sources.source { |src|
|
23
|
+
# # and so on
|
24
|
+
# }
|
25
|
+
# }
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
# @see http://builder.rubyforge.org/classes/Builder/XmlMarkup.html
|
29
|
+
# @return [String] the constructed XML
|
30
|
+
def self.xml(root_name, root_attributes={}, &block)
|
31
|
+
root_attributes['xmlns'] = xml_namespace['psc']
|
32
|
+
Builder::XmlMarkup.new(:indent => 2).tag!(root_name, root_attributes, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# @private
|
37
|
+
XML_NAMESPACE = { 'psc' => 'http://bioinformatics.northwestern.edu/ns/psc' }.freeze
|
38
|
+
|
39
|
+
##
|
40
|
+
# Provides an XML namespace mapping suitable for use with
|
41
|
+
# Nokogiri. The prefix `psc` is mapped to PSC's namespace.
|
42
|
+
#
|
43
|
+
# @return [Hash<String, String>] the mapping
|
44
|
+
def self.xml_namespace
|
45
|
+
XML_NAMESPACE
|
46
|
+
end
|
47
|
+
end
|
data/lib/psc/client.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'psc'
|
2
|
+
|
3
|
+
module Psc
|
4
|
+
##
|
5
|
+
# A high-level interface to a PSC instance's API. This class does
|
6
|
+
# not expose everything you can do with the API — only a few
|
7
|
+
# of the more common elements. Refer to the API documentation and
|
8
|
+
# use {Psc::Connection} for complete access.
|
9
|
+
class Client
|
10
|
+
##
|
11
|
+
# The connection that the client is using to access PSC. Use it to
|
12
|
+
# make requests that the high-level interface doesn't support.
|
13
|
+
#
|
14
|
+
# @return [Psc::Connection]
|
15
|
+
attr_reader :connection
|
16
|
+
|
17
|
+
##
|
18
|
+
# Create a new client instance. The given url and options will be
|
19
|
+
# used to create a {Psc::Connection} for the client to use; see
|
20
|
+
# that class for more details about what is permitted
|
21
|
+
def initialize(url, options, &block)
|
22
|
+
@connection = Psc::Connection.new(url, options, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Returns an array of hashes describing the studies in the system.
|
27
|
+
# The contents are from the JSON representation of the `/studies`
|
28
|
+
# resource.
|
29
|
+
#
|
30
|
+
# @return [Array<Hash>]
|
31
|
+
def studies
|
32
|
+
connection.get('studies.json').body['studies']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'psc'
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_stack'
|
4
|
+
|
5
|
+
module Psc
|
6
|
+
##
|
7
|
+
# A `Faraday::Connection` set up for use with Patient Study
|
8
|
+
# Calendar. See the {file:README.md} for a couple of examples.
|
9
|
+
#
|
10
|
+
# @see https://github.com/technoweenie/faraday
|
11
|
+
# @see https://github.com/mislav/faraday-stack
|
12
|
+
class Connection < ::Faraday::Connection
|
13
|
+
##
|
14
|
+
# Create a new PSC connection. This is a `Faraday::Connection`
|
15
|
+
# with the following middleware:
|
16
|
+
#
|
17
|
+
# * Either {Psc::Faraday::HttpBasic} or {Psc::Faraday::PscToken}
|
18
|
+
# depending on the contents of the `:authenticator` option
|
19
|
+
# * {Psc::Faraday::StringIsXml}
|
20
|
+
# * `::Faraday::Request::JSON`
|
21
|
+
# * `::Faraday::Request::UrlEncoded`
|
22
|
+
# * `::FaradayStack::ResponseXML` for content-type text/xml
|
23
|
+
# * `::FaradayStack::ResponseJSON` for content-type application/json
|
24
|
+
# * `::Faraday::Adapter::NetHttp`
|
25
|
+
#
|
26
|
+
# If a block is provided, it will receive the Faraday builder so
|
27
|
+
# that you can append more middleware. If you provide your own
|
28
|
+
# adapter, the `net/http` adapter will not be appended.
|
29
|
+
#
|
30
|
+
# @param [String] url the base URL for your PSC instance
|
31
|
+
# @param [Hash] options the options for the connection. These are
|
32
|
+
# same as accepted by `Faraday::Connection`, plus:
|
33
|
+
# @option options [Hash] :authenticator parameters for the
|
34
|
+
# authentication middleware. These are detailed in the {file:README.md}.
|
35
|
+
# @yield [builder] (optional)
|
36
|
+
def initialize(url, options)
|
37
|
+
super do |builder|
|
38
|
+
builder.use *authentication_middleware(options[:authenticator])
|
39
|
+
builder.use Psc::Faraday::StringIsXml
|
40
|
+
builder.request :json
|
41
|
+
builder.request :url_encoded
|
42
|
+
builder.use FaradayStack::ResponseXML, :content_type => 'text/xml'
|
43
|
+
builder.use FaradayStack::ResponseJSON, :content_type => 'application/json'
|
44
|
+
|
45
|
+
if block_given?
|
46
|
+
yield builder
|
47
|
+
end
|
48
|
+
|
49
|
+
builder.adapter :net_http unless has_adapter?(builder)
|
50
|
+
end
|
51
|
+
|
52
|
+
unless self.path_prefix =~ %r{/api/v1$}
|
53
|
+
self.path_prefix = if self.path_prefix == '/'
|
54
|
+
'/api/v1'
|
55
|
+
else
|
56
|
+
self.path_prefix + '/api/v1'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def authentication_middleware(authenticator)
|
64
|
+
unless authenticator
|
65
|
+
raise 'No authentication method specified. Please include the :authenticator option.'
|
66
|
+
end
|
67
|
+
|
68
|
+
kind = authenticator.keys.first
|
69
|
+
|
70
|
+
case kind
|
71
|
+
when :basic
|
72
|
+
[Psc::Faraday::HttpBasic, *authenticator[kind]]
|
73
|
+
when :token
|
74
|
+
[Psc::Faraday::PscToken, authenticator[kind]]
|
75
|
+
else
|
76
|
+
raise "Unsupported authentication method #{kind.inspect}."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def has_adapter?(builder)
|
81
|
+
builder.handlers.detect { |h| has_superclass?(h.klass, ::Faraday::Adapter) }
|
82
|
+
end
|
83
|
+
|
84
|
+
# It seems like there must be a builtin for this, but I'm not
|
85
|
+
# finding it.
|
86
|
+
def has_superclass?(child, ancestor)
|
87
|
+
if child.superclass == ancestor
|
88
|
+
true
|
89
|
+
elsif child.superclass.nil?
|
90
|
+
false
|
91
|
+
else
|
92
|
+
has_superclass?(child.superclass, ancestor)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/psc/faraday.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'psc'
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
##
|
6
|
+
# The custom Faraday middleware used in `psc.rb`.
|
7
|
+
module Psc::Faraday
|
8
|
+
autoload :HttpBasic, 'psc/faraday/http_basic'
|
9
|
+
autoload :PscToken, 'psc/faraday/psc_token'
|
10
|
+
autoload :StringIsXml, 'psc/faraday/string_is_xml'
|
11
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'psc/faraday'
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
module Psc::Faraday
|
6
|
+
##
|
7
|
+
# Faraday middleware that implements [HTTP Basic][]. This is not
|
8
|
+
# PSC-specific, and Faraday even includes HTTP Basic support, but
|
9
|
+
# Faraday's support is not implemented as middleware. Using
|
10
|
+
# middleware makes setting up a connection based on the
|
11
|
+
# `:authenticator` option cleaner.
|
12
|
+
#
|
13
|
+
# [HTTP Basic]: http://www.ietf.org/rfc/rfc2617.txt
|
14
|
+
class HttpBasic
|
15
|
+
##
|
16
|
+
# Create an instance of the middleware.
|
17
|
+
#
|
18
|
+
# @param [#call] app
|
19
|
+
# @param [String] username
|
20
|
+
# @param [String] password
|
21
|
+
def initialize(app, username, password)
|
22
|
+
@app = app
|
23
|
+
@header_value = "Basic #{Base64.encode64([username, password].join(':')).strip}"
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Sets the `Authorization` request header using the HTTP Basic
|
28
|
+
# scheme.
|
29
|
+
def call(env)
|
30
|
+
env[:request_headers]['Authorization'] = @header_value
|
31
|
+
|
32
|
+
@app.call(env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'psc/faraday'
|
2
|
+
|
3
|
+
module Psc
|
4
|
+
module Faraday
|
5
|
+
##
|
6
|
+
# Faraday middleware that implements the `psc_token`
|
7
|
+
# authentication type. Tokens may either be static or computed
|
8
|
+
# per request.
|
9
|
+
class PscToken
|
10
|
+
##
|
11
|
+
# Create a new instance of the middleware.
|
12
|
+
#
|
13
|
+
# @param [#call] app
|
14
|
+
# @param [#call,String] token_or_creator if the value for this
|
15
|
+
# parameter responds to `call`, it will be called to create a
|
16
|
+
# token on each request. Otherwise it will be used as a static
|
17
|
+
# token value.
|
18
|
+
def initialize(app, token_or_creator)
|
19
|
+
@app = app
|
20
|
+
if token_or_creator.respond_to?(:call)
|
21
|
+
@token_creator = token_or_creator
|
22
|
+
else
|
23
|
+
@token_creator = lambda { token_or_creator }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Adds the `Authorization` header using the configured token creator.
|
29
|
+
def call(env)
|
30
|
+
env[:request_headers]['Authorization'] = "psc_token #{token}"
|
31
|
+
|
32
|
+
@app.call
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def token
|
38
|
+
@token_creator.call
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|