xporter_on_demand 0.1.4 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8f95f8eb066154b26d9af9347204d471d2118b738b814a3cee21b73420b52ed
4
- data.tar.gz: 8512ffd4570508bf6ff60db8ca591259bf7ec56336527e74d734488ad3db1fc3
3
+ metadata.gz: 2650748b5f2276cc4f3b0be0eeea8b7f7ce2e3c95ca22ecde37521d5863e53d4
4
+ data.tar.gz: 6e2e16eb2a12043f080cb67ce7c29ec495796193cbd3acef48ef2493b19e0a3b
5
5
  SHA512:
6
- metadata.gz: 62e4ba2f8b38fbf9858e2f31f502a69b331a986e9becff20f7a824ab5e7f6b3c04d71b64d03d3f14df9dc979eb03edf7b2346ab53053eee9f43bf5c9e7f3ada5
7
- data.tar.gz: a5b5522e4b962afc488d9a1d99aafdeb65a107478799c94b511cf78eb5189474d0239d1d10e7c4202ba50d7aa79df68eae97bf0ac7fbd019cb6ee29c96907a4c
6
+ metadata.gz: a1c2e2f64d3fb7fa4b6a7aa9809820531d6668688b14cd0b34efcef969d280c1bc016844988325a87167574b46a2c33894926df84433625c9e02269c4540afc4
7
+ data.tar.gz: 8fb6f4e7fbc24cca17be7788757151a99729db6afcdd481450c73f5fb99c7bec189838205d86aac9120d6a2889398c9d4720d52b26b2e1268ccf4b2f0243051c
data/README.md CHANGED
@@ -26,3 +26,51 @@ student_results = client.query(students_endpoint)
26
26
  # Retrieve all pages
27
27
  student_results.fetch_all
28
28
  ```
29
+
30
+ ## Using the Invitation API
31
+
32
+ ```ruby
33
+
34
+ # Create your registration object
35
+ reg = XporterOnDemand::Registration.new do |r|
36
+ r.registration_type = 'Test' # Defaults to 'Live'
37
+ r.partner_id = 'your-partner-id'
38
+ r.app_management_secret = 'your-app-management-secret'
39
+ end
40
+
41
+ # Build your school with at the required parameters
42
+ school = {
43
+ lea_code: 123, # Required
44
+ dfes_code: 4567, # Required
45
+ school_name: 'Test School', # Required
46
+ school_contact_first_name: 'Joe', # Required
47
+ school_contact_last_name: 'Bloggs', # Required
48
+ school_contact_email: 'joe.bloggs@email.com', # Required
49
+ school_contact_phone: '01234 567890', # Required
50
+ school_contact: 'Joe Bloggs',
51
+ school_technical_contact_name: 'Jim Bloggs',
52
+ school_technical_contact_email: 'jim.bloggs@email.com',
53
+ school_technical_contact_phone: '01234 567890',
54
+ partner_application_id: 'your-partner-id', # Required
55
+ partner_name: 'your-registered-name', # Required
56
+ partner_registered_email: 'your-registered-email', # Required
57
+ we_accept_groupcall_usage_policy: true, # Required
58
+ }
59
+
60
+ # Add school to the registration object. Multiple schools can be added
61
+ reg.add_school(school)
62
+
63
+ # Send registrations
64
+ reg.register
65
+
66
+ # Will return a boolean outlining whether or not ALL registrations were successful.
67
+ # Any error messages will be assigned to the registration object or the
68
+ # individual schools eg.
69
+
70
+ reg.message
71
+ # => 'Unauthorized: ApplicationId header missing or incorrect'
72
+
73
+ reg.schools.first.message
74
+ # => 'School not found in EduBase'
75
+
76
+ ```
@@ -0,0 +1,110 @@
1
+ require 'xporter_on_demand/utils'
2
+ require 'base64'
3
+
4
+ module XporterOnDemand
5
+ class Registration
6
+ include XporterOnDemand::Utils
7
+
8
+ attr_reader :schools, :message
9
+ attr_accessor :registration_type, :partner_id, :app_management_secret
10
+
11
+ SCHOOL_ATTRIBUTES = %i(
12
+ lea_code
13
+ dfes_code
14
+ school_name
15
+ school_contact_first_name
16
+ school_contact_last_name
17
+ school_contact_email
18
+ school_contact_phone
19
+ school_contact
20
+ school_technical_contact_name
21
+ school_technical_contact_email
22
+ school_technical_contact_phone
23
+ partner_application_id
24
+ partner_name
25
+ partner_registered_email
26
+ scopes_to_authorise
27
+ we_accept_groupcall_usage_policy
28
+ )
29
+
30
+ School = Struct.new(*SCHOOL_ATTRIBUTES) do
31
+ attr_accessor :status, :message
32
+
33
+ def camelize
34
+ to_h.transform_keys{ |k| k.to_s.camelcase }.reject{ |_k, v| v.nil? || (String === v && v.empty?) }
35
+ end
36
+ end
37
+
38
+ def initialize(args = {})
39
+ @schools = Set.new
40
+
41
+ if block_given?
42
+ yield self
43
+ else
44
+ @registration_type = args[:registration_type] || 'Live'
45
+ @partner_id = args[:partner_id]
46
+ @app_management_secret = args[:app_management_secret]
47
+ end
48
+ end
49
+
50
+ def add_school(param_hash = {})
51
+ attributes = SCHOOL_ATTRIBUTES.each_with_object({}) do |key, hash|
52
+ hash[key] = param_hash[key]
53
+ end
54
+
55
+ if School.const_defined? 'ActiveModel::Model'
56
+ @schools << School.new.tap{ |s| s.assign_attributes attributes }
57
+ else
58
+ @schools << School.new(*attributes.values)
59
+ end
60
+ end
61
+
62
+ def register
63
+ timestamp = DateTime.current.strftime("%FT%T")
64
+ auth = generate_hash(timestamp: timestamp)
65
+
66
+ args = {
67
+ url: REGISTRATION_PATH,
68
+ headers: {
69
+ 'ApplicationId': @partner_id,
70
+ 'DateTime': timestamp,
71
+ 'Authorization': "Groupcall #{auth}",
72
+ },
73
+ body: to_json,
74
+ }
75
+
76
+ response = post(args)
77
+
78
+ if response['Schools']
79
+ response['Schools'].all? do |school|
80
+ s = get_school(school['LeaCode'], school['DfesCode'])
81
+ s.status = school['Status']
82
+ s.message = school['Message']
83
+
84
+ school['Status'] == 'OK'
85
+ end
86
+ else
87
+ @message = response['Message']
88
+ false
89
+ end
90
+ end
91
+
92
+ def get_school(lea, dfes)
93
+ @schools.find{ |sch| sch.lea_code == lea && sch.dfes_code == dfes }
94
+ end
95
+
96
+ def to_json
97
+ { Schools: @schools.map(&:camelize), RegistrationType: @registration_type }.to_json
98
+ end
99
+
100
+ def generate_hash(secret: @app_management_secret, timestamp:, content: to_json)
101
+ raise ArgumentError, 'Must supply your App Management Secret' unless secret
102
+ raise ArgumentError, 'Must supply at least one school' if @schools.empty?
103
+
104
+ b64 = Base64.strict_encode64(content + timestamp + secret)
105
+
106
+ sha256 = OpenSSL::Digest.new('sha256')
107
+ OpenSSL::HMAC.hexdigest(sha256, secret, b64).upcase
108
+ end
109
+ end
110
+ end
@@ -1,6 +1,7 @@
1
1
  module XporterOnDemand
2
2
  class Token < Client
3
3
  def initialize(*args)
4
+ @loaded = false
4
5
  @options = args.last.is_a?(Hash) ? args.pop : {}
5
6
  @options[:url] ||= STS_PATH
6
7
 
@@ -14,7 +15,20 @@ module XporterOnDemand
14
15
  def retrieve
15
16
  result = post(@options.merge(body: @request_body.to_json))
16
17
  assign_attributes(result)
18
+ @loaded = true
17
19
  self
18
20
  end
21
+
22
+ def validate
23
+ dont_raise_exception{ retrieve }
24
+
25
+ if token
26
+ :valid
27
+ elsif try(:authorisation_paused)
28
+ :paused
29
+ else
30
+ :invalid
31
+ end
32
+ end
19
33
  end
20
34
  end
@@ -18,7 +18,7 @@ module XporterOnDemand
18
18
 
19
19
  def handle_exceptions(response)
20
20
  response_body = JSON.parse(response.body || {})
21
- raise response_body["ExceptionMessage"] if response_body["ExceptionMessage"]
21
+ raise response_body["ExceptionMessage"] if response_body["ExceptionMessage"] && !@dont_raise_exception
22
22
  end
23
23
 
24
24
  def parameterize(sym)
@@ -68,5 +68,12 @@ module XporterOnDemand
68
68
  enum
69
69
  end
70
70
  end
71
+
72
+ def dont_raise_exception
73
+ @dont_raise_exception = true
74
+ yield
75
+ ensure
76
+ @dont_raise_exception = false
77
+ end
71
78
  end
72
79
  end
@@ -1,3 +1,3 @@
1
1
  module XporterOnDemand
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -14,9 +14,11 @@ require 'xporter_on_demand/version'
14
14
  require 'xporter_on_demand/result/base'
15
15
  require 'xporter_on_demand/result/result_set'
16
16
  require 'xporter_on_demand/result/serialiser'
17
+ require 'xporter_on_demand/registration'
17
18
 
18
19
  module XporterOnDemand
19
- API_PATH = "https://xporter.groupcall.com/api/v1/"
20
- STS_PATH = "https://login.groupcall.com/idaas/sts/STS/GetToken"
21
- META_KEYS = %w(ChangedRows DbStatus Meta Pagination)
20
+ API_PATH = "https://xporter.groupcall.com/api/v1/"
21
+ STS_PATH = "https://login.groupcall.com/idaas/sts/STS/GetToken"
22
+ META_KEYS = %w(ChangedRows DbStatus Meta Pagination)
23
+ REGISTRATION_PATH = "https://manage.groupcall.com/API/XporterOnDemand/SchoolRegister"
22
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xporter_on_demand
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Green
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-29 00:00:00.000000000 Z
11
+ date: 2019-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpi
@@ -28,20 +28,20 @@ dependencies:
28
28
  name: httpclient
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 2.8.3
34
- - - ">="
34
+ - - "~>"
35
35
  - !ruby/object:Gem::Version
36
36
  version: 2.8.3
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - "~>"
41
+ - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  version: 2.8.3
44
- - - ">="
44
+ - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: 2.8.3
47
47
  - !ruby/object:Gem::Dependency
@@ -120,6 +120,7 @@ files:
120
120
  - lib/xporter_on_demand/client.rb
121
121
  - lib/xporter_on_demand/endpoint.rb
122
122
  - lib/xporter_on_demand/factory.rb
123
+ - lib/xporter_on_demand/registration.rb
123
124
  - lib/xporter_on_demand/result/base.rb
124
125
  - lib/xporter_on_demand/result/result_set.rb
125
126
  - lib/xporter_on_demand/result/serialiser.rb
@@ -146,8 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
147
  - !ruby/object:Gem::Version
147
148
  version: '0'
148
149
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.7.6
150
+ rubygems_version: 3.0.1
151
151
  signing_key:
152
152
  specification_version: 4
153
153
  summary: Ruby client for the Xporter on Demand API.