psc 0.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.
- 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
|