strongmind-platform-sdk 3.1.4 → 3.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: e53b5cd02f0dfaad2c3099aee4a574f1bdfe3aea6e0bfb81afb592ea93c5ceab
4
- data.tar.gz: 8c723a651bef3f8fd54a8fd0804ecda6d86434519ee52b13b5ed4a3e007f3671
3
+ metadata.gz: 4d3e7692a1585b6660f3127296b51489fe91abe306d673149a089562d05e9637
4
+ data.tar.gz: 7922d450c254e2dc3dece30d5440f8a56232039327400740198e4fb4d032e645
5
5
  SHA512:
6
- metadata.gz: a01e8b539c2497bd95b5ce578df052c63638c478c7591b977e1e98e352899a0cab12a21114c18e55b91f45bf3e3545f0e2cd952424d5ab81b6100cab2d105782
7
- data.tar.gz: 0a797bca0b13a2c16c30fdd89b191a47611860abb3b1c35369a5be62da67fc3aa626f2e969ddbf565a48e0aa266db12b63af2c56a6bc2bc46fad533c2e590848
6
+ metadata.gz: ea6585723a59c9f2731141f41bff045fc43ea18a61a7767e74cb75f3f317e4d800e4088669ebe43d4da7f7707234b8543f7764883187415a1bc59a27ff4db124
7
+ data.tar.gz: ebabea43dba9197fa0ef7cfec80fa894a004458f25a10b2a41de6ae7234511ec6cc321cb3a67daa42f85286bf9614ff80580abd7a189732ea2af7260287b452e
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strongmind-platform-sdk (3.1.4)
4
+ strongmind-platform-sdk (3.2.0)
5
5
  aws-sdk-secretsmanager (~> 1.66)
6
6
  devise
7
7
  faraday (~> 2.5, >= 2.5.2)
8
8
  faraday-retry
9
+ jwt
9
10
  omniauth
10
11
  omniauth-rails_csrf_protection
11
12
  omniauth_openid_connect
@@ -39,16 +40,16 @@ GEM
39
40
  ast (2.4.2)
40
41
  attr_required (1.0.1)
41
42
  aws-eventstream (1.2.0)
42
- aws-partitions (1.834.0)
43
+ aws-partitions (1.843.0)
43
44
  aws-sdk-core (3.185.1)
44
45
  aws-eventstream (~> 1, >= 1.0.2)
45
46
  aws-partitions (~> 1, >= 1.651.0)
46
47
  aws-sigv4 (~> 1.5)
47
48
  jmespath (~> 1, >= 1.6.1)
48
- aws-sdk-secretsmanager (1.83.0)
49
+ aws-sdk-secretsmanager (1.84.0)
49
50
  aws-sdk-core (~> 3, >= 3.184.0)
50
51
  aws-sigv4 (~> 1.1)
51
- aws-sigv4 (1.6.0)
52
+ aws-sigv4 (1.6.1)
52
53
  aws-eventstream (~> 1, >= 1.0.2)
53
54
  bcrypt (3.1.19)
54
55
  bindata (2.4.15)
@@ -56,7 +57,7 @@ GEM
56
57
  concurrent-ruby (1.2.2)
57
58
  crass (1.0.6)
58
59
  date (3.3.3)
59
- devise (4.9.2)
60
+ devise (4.9.3)
60
61
  bcrypt (~> 3.0)
61
62
  orm_adapter (~> 0.1)
62
63
  railties (>= 4.1.0)
@@ -91,7 +92,7 @@ GEM
91
92
  faraday (~> 2.0)
92
93
  faraday-follow_redirects
93
94
  jwt (1.5.6)
94
- loofah (2.21.3)
95
+ loofah (2.21.4)
95
96
  crass (~> 1.0.2)
96
97
  nokogiri (>= 1.12.0)
97
98
  mail (2.8.1)
@@ -101,9 +102,9 @@ GEM
101
102
  net-smtp
102
103
  method_source (1.0.0)
103
104
  mini_mime (1.1.5)
104
- mini_portile2 (2.8.4)
105
+ mini_portile2 (2.8.5)
105
106
  minitest (5.18.0)
106
- net-imap (0.4.1)
107
+ net-imap (0.4.2)
107
108
  date
108
109
  net-protocol
109
110
  net-pop (0.1.2)
@@ -177,7 +178,7 @@ GEM
177
178
  rainbow (3.1.1)
178
179
  rake (13.0.6)
179
180
  regexp_parser (2.8.0)
180
- responders (3.1.0)
181
+ responders (3.1.1)
181
182
  actionpack (>= 5.2)
182
183
  railties (>= 5.2)
183
184
  rexml (3.2.5)
@@ -216,7 +217,7 @@ GEM
216
217
  attr_required (>= 0.0.5)
217
218
  faraday (~> 2.0)
218
219
  faraday-follow_redirects
219
- thor (1.2.2)
220
+ thor (1.3.0)
220
221
  timeout (0.4.0)
221
222
  typhoeus (1.4.0)
222
223
  ethon (>= 0.9.0)
data/README.md CHANGED
@@ -11,7 +11,7 @@ First [configure your GitHub credentials](#configure-github-credentials)
11
11
  Install the gem and add to the application's Gemfile by executing:
12
12
 
13
13
  ```
14
- gem "strongmind-platform-sdk", "~> 3.1.4"
14
+ gem "strongmind-platform-sdk", "~> 3.2.0"
15
15
  ```
16
16
 
17
17
  If bundler is not being used to manage dependencies, install the gem by executing:
@@ -110,3 +110,6 @@ Create PowerSchool Client:
110
110
 
111
111
  Create IdMapper Client:
112
112
  `id_mapper_client = PlatformSdk::IdMapper::Client.new(domain: 'ID_MAPPER_DOMAIN', token: 'SECRET_TOKEN')`
113
+
114
+ Create Pencil Spaces Client:
115
+ `pencil_spaces_client = PlatformSdk::PencilSpaces::Client.new('BASE_URL', 'BEARER_TOKEN')`
@@ -4,6 +4,7 @@ require "date"
4
4
  require "faraday"
5
5
  require "faraday/net_http"
6
6
  require "json"
7
+ require "jwt"
7
8
 
8
9
  require "platform_sdk/identity/clients"
9
10
 
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformSdk
4
+ module PencilSpaces
5
+ # OneRoster Client which wraps the swagger generated OneRoster Management APIs
6
+ class Client
7
+ attr_reader :access_token, :base_url, :conn
8
+
9
+ # The API only supports these roles for API managed users
10
+ VALID_API_USER_ROLES = %i[Teacher Student].freeze
11
+ # The API only supports these roles for users in a space
12
+ VALID_SPACE_ROLES = %i[host participant].freeze
13
+ DEFAULT_VISIBILITY = "private"
14
+
15
+ def initialize(base_url, access_token, conn: nil)
16
+ @access_token = access_token
17
+ @base_url = base_url
18
+ @conn = conn || build_connection
19
+ end
20
+
21
+ # Get a list of Spaces accessible by the account associated with your API key
22
+ # @param [Hash] opts the optional parameters
23
+ # @option opts [Integer] :page_number **(Optional)** - The page number of the items to return. The number of items in a page is controlled by the `pageSize` parameter.
24
+ # @option opts [Integer] :page_size **(Optional)** - The max number of items to return. Setting a larger `pageSize` may result in a longer querying times
25
+ # @option opts [String] :filters **(Optional)** - A base64 encoded string of the filters you wish to apply to the query. See `spacesFilterSchema` for details on all the filters applicable to your query
26
+ # @return [JSON]
27
+ def spaces(opts = {})
28
+ # query parameters
29
+ query_params = opts[:query_params] || {}
30
+ query_params[:pageNumber] = opts[:page_number] unless opts[:page_number].nil?
31
+ query_params[:pageSize] = opts[:page_size] unless opts[:page_size].nil?
32
+ query_params[:filters] = opts[:filters] unless opts[:filters].nil?
33
+
34
+ response = get("/spaces", query_params)
35
+ response.body
36
+ end
37
+
38
+ # Get details for a particular Space
39
+ # @param [String] space_id
40
+ # @return [JSON] The space object for the requested space_id
41
+ def space(space_id)
42
+ resource_path = "/spaces/#{space_id}"
43
+ response = get(resource_path)
44
+ response.body
45
+ end
46
+
47
+ # Create a new Space
48
+ # @param [String] title
49
+ # @param [Array<PlatformSdk::PencilSpaces::Models::UserWithRole>] hosts **(Optional)** Role is not required
50
+ # @param [Array<PlatformSdk::PencilSpaces::Models::UserWithRole>] participants **(Optional)** Role is not required
51
+ # @param [String] visibility **(Optional)** Default is "private"
52
+ # @return [JSON] The newly created space
53
+ def create_space(title, hosts: [], participants: [], visibility: DEFAULT_VISIBILITY)
54
+ body = {
55
+ title:,
56
+ visibility:,
57
+ hosts: hosts.map(&:as_json),
58
+ participants: participants.map(&:as_json),
59
+ notifyInvitees: false
60
+ }
61
+ response = post("/spaces/create", body.to_json)
62
+ response.body
63
+ end
64
+
65
+ # Get a list of Users accessible by the account associated with your API key
66
+ # @param [Hash] opts the optional parameters
67
+ # @option opts [Integer] :page_number **(Optional)** - The page number of the items to return. The number of items in a page is controlled by the &#x60;pageSize&#x60; parameter.
68
+ # @option opts [Integer] :page_size **(Optional)** - The max number of items to return. Setting a larger &#x60;pageSize&#x60; may result in a longer querying times
69
+ # @option opts [String] :filters **(Optional)** - A base64 encoded string of the filters you wish to apply to the query. See &#x60;spacesFilterSchema&#x60; for details on all the filters applicable to your query
70
+ # @return [JSON] A list of Pencil Spaces users
71
+ def users(opts = {})
72
+ # query parameters
73
+ query_params = opts[:query_params] || {}
74
+ query_params[:pageNumber] = opts[:page_number] unless opts[:page_number].nil?
75
+ query_params[:pageSize] = opts[:page_size] unless opts[:page_size].nil?
76
+ query_params[:filters] = opts[:filters] unless opts[:filters].nil?
77
+
78
+ response = get("/users", query_params)
79
+ response.body
80
+ end
81
+
82
+ # Get details for a particular User
83
+ # @param [String] user_id
84
+ # @return [JSON] The user object for the requested user_id
85
+ def user(user_id)
86
+ response = get("/users/#{user_id}")
87
+ response.body
88
+ end
89
+
90
+ # Create a login link for a user
91
+ # @param [String] user_id
92
+ # @param [String] redirect_url **(Optional)** The URL to redirect the user to after they login
93
+ # @return [JSON] JSON with a login link for the user, i.e. { "url" => "https://pencilspaces.com/login?token=123" }
94
+ def authorize_user(user_id, redirect_url: nil)
95
+ raise ArgumentError, "user_id must have a value" if user_id.nil?
96
+
97
+ query_params = {}
98
+ query_params[:redirectUrl] = redirect_url unless redirect_url.nil?
99
+ response = get("/users/#{user_id}/authorize", query_params)
100
+ response.body
101
+ end
102
+
103
+ def create_api_user(name, role)
104
+ validate_api_user_role!(role)
105
+ body = { name:, userRole: role }
106
+ response = @conn.post("/users/createAPIUser", body.to_json)
107
+ response.body
108
+ end
109
+
110
+ # Update users in a space
111
+ # @param [String] space_id
112
+ # @param [Array<PlatformSdk::PencilSpaces::Models::UserWithRole>] users_to_add **(Optional)** Role is required
113
+ # @param [Array<PlatformSdk::PencilSpaces::Models::UserWithRole>] users_to_modify **(Optional)** Role is required
114
+ # @param [Array<PlatformSdk::PencilSpaces::Models::UserWithRole>] users_to_remove **(Optional)**
115
+ # @return [JSON] The updated space
116
+ def update_users_in_space(space_id, users_to_add: [], users_to_modify: [], users_to_remove: [])
117
+ validate_update_users_in_space_args!(space_id, users_to_add, users_to_modify, users_to_remove)
118
+
119
+ body = {
120
+ notifyInvitees: false,
121
+ addUsers: users_to_add.map(&:as_json),
122
+ modifyUsers: users_to_modify.map(&:as_json),
123
+ removeUsers: users_to_remove.map(&:as_json)
124
+ }
125
+
126
+ response = patch("/spaces/#{space_id}/updateUsers", body.to_json)
127
+ response.body
128
+ end
129
+
130
+ private
131
+
132
+ def build_connection
133
+ Faraday.new(@base_url) do |faraday|
134
+ faraday.headers = default_headers
135
+ faraday.adapter Faraday.default_adapter
136
+ faraday.response :json, content_type: /\bjson$/, parser_options: { symbolize_names: true }
137
+ faraday.response :raise_error
138
+ end
139
+ end
140
+
141
+ def default_headers
142
+ {
143
+ "Content-Type" => "application/json",
144
+ "Authorization" => "Bearer #{access_token}"
145
+ }
146
+ end
147
+
148
+ def get(path, params = {})
149
+ @conn.get(path, params)
150
+ end
151
+
152
+ def post(path, body)
153
+ @conn.post(path, body)
154
+ end
155
+
156
+ def patch(path, body)
157
+ @conn.patch(path, body)
158
+ end
159
+
160
+ def validate_update_users_in_space_args!(space_id, users_to_add, users_to_modify, users_to_remove)
161
+ raise ArgumentError, "space_id must have a value" if space_id.nil?
162
+
163
+ if [users_to_add, users_to_modify, users_to_remove].all?(&:empty?)
164
+ raise ArgumentError, "Must provide at least one of users_to_add, users_to_modify, users_to_remove"
165
+ end
166
+
167
+ needs_role = users_to_add + users_to_modify
168
+ needs_role.each do |user|
169
+ if user.class != PlatformSdk::PencilSpaces::Models::UserWithRole
170
+ raise ArgumentError, "users_to_add/users_to_modify must be an array of UserWithRole objects"
171
+ end
172
+
173
+ raise ArgumentError, "users_to_add and users_to_modify objects must have a role" if user.role.nil?
174
+ end
175
+
176
+ users_to_remove.each do |user|
177
+ if user.class != PlatformSdk::PencilSpaces::Models::UserWithRole
178
+ raise ArgumentError, "users_to_remove must be an array of UserWithRole objects (role not required)"
179
+ end
180
+ end
181
+ end
182
+
183
+ def validate_api_user_role!(role)
184
+ return if VALID_API_USER_ROLES.include?(role)
185
+
186
+ raise ArgumentError, "Invalid role: #{role}, must be one of #{VALID_API_USER_ROLES}"
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformSdk
4
+ module PencilSpaces
5
+ module Constants
6
+ TEACHER_ROLE = :Teacher
7
+ STUDENT_ROLE = :Student
8
+ ADMIN_ROLE = :InstitutionAdmin
9
+ SPACE_HOST_ROLE = :host
10
+ SPACE_PARTICIPANT_ROLE = :participant
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformSdk
4
+ module PencilSpaces
5
+ module Models
6
+ class UserWithRole
7
+ attr_accessor :role, :user_id
8
+
9
+ VALID_ROLES = %i[host participant].freeze
10
+
11
+ def initialize(user_id, user_role_in_space = nil)
12
+ @user_id = user_id
13
+ return unless user_role_in_space
14
+
15
+ validate_role!(user_role_in_space)
16
+ @role = user_role_in_space
17
+ end
18
+
19
+ def as_json
20
+ json = {}
21
+ instance_variables.each do |var|
22
+ key = var.to_s.delete("@")
23
+ key = "userId" if key == "user_id"
24
+ json[key] = instance_variable_get(var).to_s if instance_variable_get(var)
25
+ end
26
+ json
27
+ end
28
+
29
+ private
30
+
31
+ def validate_role!(role)
32
+ return if VALID_ROLES.include?(role)
33
+
34
+ raise ArgumentError, "Invalid role: #{role}, must be one of #{VALID_ROLES}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "platform_sdk/pencil_spaces/models/user_with_role"
4
+
5
+ module PlatformSdk
6
+ module PencilSpaces
7
+ module Models
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "platform_sdk/pencil_spaces/client"
4
+ require "platform_sdk/pencil_spaces/constants"
5
+ require "platform_sdk/pencil_spaces/models"
6
+
7
+
8
+ module PlatformSdk
9
+ module PencilSpaces
10
+ class Error < StandardError; end
11
+ end
12
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PlatformSdk
4
- VERSION = "3.1.4"
4
+ VERSION = "3.2.0"
5
5
  end
data/lib/platform_sdk.rb CHANGED
@@ -8,6 +8,7 @@ require "platform_sdk/aws"
8
8
  require "platform_sdk/id_mapper"
9
9
  require "platform_sdk/edkey"
10
10
  require "platform_sdk/data_pipeline"
11
+ require "platform_sdk/pencil_spaces"
11
12
 
12
13
  module PlatformSdk
13
14
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strongmind-platform-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.4
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Platform Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-10 00:00:00.000000000 Z
11
+ date: 2023-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -72,6 +72,20 @@ dependencies:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: jwt
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
75
89
  - !ruby/object:Gem::Dependency
76
90
  name: aws-sdk-secretsmanager
77
91
  requirement: !ruby/object:Gem::Requirement
@@ -185,6 +199,11 @@ files:
185
199
  - lib/platform_sdk/identity/clients.rb
186
200
  - lib/platform_sdk/one_roster.rb
187
201
  - lib/platform_sdk/one_roster/client.rb
202
+ - lib/platform_sdk/pencil_spaces.rb
203
+ - lib/platform_sdk/pencil_spaces/client.rb
204
+ - lib/platform_sdk/pencil_spaces/constants.rb
205
+ - lib/platform_sdk/pencil_spaces/models.rb
206
+ - lib/platform_sdk/pencil_spaces/models/user_with_role.rb
188
207
  - lib/platform_sdk/power_school.rb
189
208
  - lib/platform_sdk/power_school/client.rb
190
209
  - lib/platform_sdk/power_school/special_program.rb