apple_class_client 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 36338de926eaa3df5b04fa4e019f9aaa8af32840
4
- data.tar.gz: 44f427bbe726a0b0a6c07b816de63f4dcc970421
3
+ metadata.gz: cf5ca3c450a74dc4dbf1f8cd9b09b6ce72ca48e8
4
+ data.tar.gz: 1f416edf07f9f13a9142616b22b85c3580427e38
5
5
  SHA512:
6
- metadata.gz: 6e6ce022f18a97fc9f092c038c28f9f3d536dfd1292b5314ac652ae1c285db7fadc55fe0db4b1f42df464da1dec03d16bb410e6b2b2d3028da919abe01155065
7
- data.tar.gz: b4462252a13ae125b63892ba47fd9387256404173f6fc46a992a547046a2f42285098f8e1aad23c489e7d07a1e68909991e76528957adad8108f5125ef090bb2
6
+ metadata.gz: e12f5ff91b5812b61bc4e234f8dab2a377fa26b7cb5492c5dd5c607a0e4aae0e6e72fa5f21ee67b7717fa291e48cdf0efc182dc9e9a6cbc0572e20220dd122f3
7
+ data.tar.gz: 1c4a46b7b2f31a6f483941b8a9447031244eca2414d157ad27a02f91a38aa47ffe71f6cb6400ba81999d433dbe71c02574a154a67f67a05d730da0c19252ea09
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0 (2017-05-23)
4
+
5
+ - Initial release
6
+
7
+
3
8
  ## 0.0.0 (2016-05-15)
4
9
 
5
10
  - Gem scaffold
@@ -35,7 +35,7 @@ This code of conduct applies both within project spaces and in public spaces
35
35
  when an individual is representing the project or its community.
36
36
 
37
37
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
- reported by contacting a project maintainer at albert@cellabus.com. All
38
+ reported by contacting a project maintainer at aywang31@gmail.com. All
39
39
  complaints will be reviewed and investigated and will result in a response that
40
40
  is deemed necessary and appropriate to the circumstances. Maintainers are
41
41
  obligated to maintain confidentiality with regard to the reporter of an
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # AppleClassClient
2
2
 
3
+ [ ![Codeship Status for albertyw/apple_class_client](https://app.codeship.com/projects/9c364080-fd10-0133-688f-7e176884dbc2/status?branch=master)](https://app.codeship.com/projects/152119)
4
+ [![Code Climate](https://codeclimate.com/github/albertyw/apple_class_client/badges/gpa.svg)](https://codeclimate.com/github/albertyw/apple_class_client)
5
+ [![Dependency Status](https://gemnasium.com/badges/github.com/albertyw/apple_class_client.svg)](https://gemnasium.com/github.com/albertyw/apple_class_client)
6
+
3
7
  This is a client for accessing Apple MDM's class, person, location, and course rosters.
4
8
 
5
9
  ## Installation
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "apple_class_client"
8
8
  spec.version = AppleClassClient::VERSION
9
9
  spec.authors = ["Albert Wang"]
10
- spec.email = ["albert@cellabus.com"]
10
+ spec.email = ["aywang31@gmail.com"]
11
11
 
12
12
  spec.summary = %q{Client for accessing Apple MDM class information}
13
13
  spec.description = %q{This is a client for accessing Apple MDM's class, person, location, and course rosters.}
@@ -19,7 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.add_dependency "oauth", "~> 0.4"
23
+ spec.add_dependency "typhoeus", [">= 0.7", "< 1.2"]
22
24
  spec.add_development_dependency "bundler", "~> 1.12"
23
- spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rake", ">= 11.0"
24
26
  spec.add_development_dependency "rspec", "~> 3.0"
25
27
  end
@@ -1,5 +1,10 @@
1
1
  require "apple_class_client/version"
2
+ require "apple_class_client/configuration"
2
3
 
3
4
  module AppleClassClient
4
- # Your code goes here...
5
+ extend Configuration
5
6
  end
7
+
8
+ require "apple_class_client/auth"
9
+ require "apple_class_client/error"
10
+ require "apple_class_client/request"
@@ -0,0 +1,51 @@
1
+ # Apple Session Authorization Token management
2
+
3
+ require "json"
4
+ require "oauth"
5
+ require File.join(File.dirname(__FILE__), "hacks", "typhoeus_request")
6
+ require "securerandom"
7
+ require "typhoeus"
8
+
9
+ module AppleClassClient
10
+ module Auth
11
+ # Apple requires a quirky OAuth 1.0a authentication to get a temporary
12
+ # X-ADM-Auth-Session key to make requests; this takes care of that
13
+
14
+ OAUTH_PATH = "/session"
15
+
16
+ def self.get_session_token
17
+ options = { method: :get, headers: AppleClassClient::Request::DEFAULT_HEADERS }
18
+ request = Typhoeus::Request.new(AppleClassClient::Request.make_url(OAUTH_PATH), options)
19
+ request.options[:headers].merge!({ "Authorization" => oauth_header(request) })
20
+ request.run
21
+ response = request.response
22
+ AppleClassClient::Error.check_request_error(response, auth: true)
23
+ parse_response response
24
+ end
25
+
26
+ def self.oauth_header(request)
27
+ consumer = OAuth::Consumer.new(
28
+ AppleClassClient.consumer_key,
29
+ AppleClassClient.consumer_secret,
30
+ site: AppleClassClient::Request.make_url(OAUTH_PATH),
31
+ )
32
+ token = OAuth::AccessToken.new(
33
+ consumer,
34
+ AppleClassClient.access_token,
35
+ AppleClassClient.access_secret,
36
+ )
37
+ oauth_params = {
38
+ consumer: consumer,
39
+ realm: "ADM",
40
+ token: token,
41
+ }
42
+ oauth_helper = OAuth::Client::Helper.new request, oauth_params.merge(request_uri: AppleClassClient::Request.make_url(OAUTH_PATH))
43
+ oauth_helper.header
44
+ end
45
+
46
+ def self.parse_response(response)
47
+ body = JSON.parse response.response_body
48
+ auth_session_token = body["auth_session_token"]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,44 @@
1
+ # Configuration for AppleClassClient
2
+ # Configuration values can be either literals or Procs; note that Procs will not
3
+ # be overwritten by AppleClassClient::Token.save_data
4
+
5
+ module AppleClassClient
6
+ module Configuration
7
+ CONFIG = {
8
+ private_key: nil, # MDM Server's private key for decrypting token files
9
+ consumer_key: nil, # Server Token information
10
+ consumer_secret: nil,
11
+ access_token: nil,
12
+ access_secret: nil,
13
+ access_token_expiry: nil,
14
+ apple_mdm_server: "https://mdmenrollment.apple.com", # Apple MDM server url
15
+ user_agent: "CellabusMDM",
16
+ }
17
+
18
+ CONFIG.freeze
19
+
20
+ attr_writer *CONFIG.keys
21
+
22
+ def method_missing(m, *_args, &_block)
23
+ if CONFIG.keys.include? m.to_sym
24
+ get_value(m)
25
+ else
26
+ raise NoMethodError, "Unknown method #{m}"
27
+ end
28
+ end
29
+
30
+ def get_value(m)
31
+ value = instance_variable_get("@#{m}")
32
+ value = get_default_value(m) if value.nil?
33
+ (value.is_a? Proc) ? value.call : value
34
+ end
35
+
36
+ def get_default_value(key)
37
+ CONFIG[key.to_sym]
38
+ end
39
+
40
+ def configure
41
+ yield self
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,47 @@
1
+ # Errors for AppleClassClient and Apple's endpoints
2
+
3
+ require 'typhoeus'
4
+
5
+ module AppleClassClient
6
+ module Error
7
+ AUTH_ERRORS = [
8
+ # Used by AppleClassClient::Auth
9
+ ["BadRequest", 400, ""],
10
+ ["Unauthorized", 401, ""],
11
+ ["Forbidden", 403, ""],
12
+ ]
13
+
14
+ ERRORS = [
15
+ # Server failures
16
+ ["InternalServerError", 500, ""],
17
+ ["ServiceUnavailable", 503, ""],
18
+
19
+ # Client errors
20
+ ["Unauthorized", 401, "UNAUTHORIZED"],
21
+ ["Forbidden", 403, "FORBIDDEN"],
22
+ ["MalformedRequest", 400, "MALFORMED_REQUEST_BODY"],
23
+ ["CursorRequired", 400, "CURSOR_REQUIRED"],
24
+ ["InvalidCursor", 400, "INVALID_CURSOR"],
25
+ ["ExpiredCursor", 400, "EXPIRED_CURSOR"],
26
+ ["TooManyRequests", 429, "TOO_MANY_REQUESTS"],
27
+ ]
28
+
29
+ def self.check_request_error(response, auth:false)
30
+ get_errors(auth: auth).each do |error_name, response_code, body|
31
+ if response.code == response_code && response.body.include?(body)
32
+ raise RequestError, error_name
33
+ end
34
+ end
35
+ if response.code != 200
36
+ raise RequestError, "GenericError"
37
+ end
38
+ end
39
+
40
+ def self.get_errors(auth:false)
41
+ auth ? AUTH_ERRORS : ERRORS
42
+ end
43
+
44
+ class RequestError < RuntimeError
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,57 @@
1
+ # This contains a few hacks that adds support for non-ancient versions of Typhoeus to
2
+ # the ancient dead ruby oauth gem
3
+
4
+ require "oauth/request_proxy/base"
5
+ require "typhoeus"
6
+ require "typhoeus/request"
7
+ require "uri"
8
+ require "cgi"
9
+
10
+ module OAuth::RequestProxy::Typhoeus
11
+ class Request < OAuth::RequestProxy::Base
12
+ # Proxy for signing Typhoeus::Request requests
13
+ # Usage example:
14
+ # oauth_params = {:consumer => oauth_consumer, :token => access_token}
15
+ # req = Typhoeus::Request.new(uri, options)
16
+ # oauth_helper = OAuth::Client::Helper.new(req, oauth_params.merge(:request_uri => uri))
17
+ # req.headers.merge!({"Authorization" => oauth_helper.header})
18
+ # hydra = Typhoeus::Hydra.new()
19
+ # hydra.queue(req)
20
+ # hydra.run
21
+ # response = req.response
22
+ proxies Typhoeus::Request
23
+
24
+ def method
25
+ request_method = request.options[:method].to_s.upcase
26
+ request_method.empty? ? "GET" : request_method
27
+ end
28
+
29
+ def uri
30
+ options[:uri].to_s
31
+ end
32
+
33
+ def parameters
34
+ if options[:clobber_request]
35
+ options[:parameters]
36
+ else
37
+ post_parameters.merge(query_parameters).merge(options[:parameters] || {})
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def query_parameters
44
+ query = URI.parse(request.url).query
45
+ query ? CGI.parse(query) : {}
46
+ end
47
+
48
+ def post_parameters
49
+ # Post params are only used if posting form data
50
+ if method == "POST"
51
+ OAuth::Helper.stringify_keys(request.params || {})
52
+ else
53
+ {}
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,41 @@
1
+ # Wrapper around requests to MDM class endpoint
2
+ # Will also handle any error conditions
3
+
4
+ require "json"
5
+ require "typhoeus"
6
+
7
+ module AppleClassClient
8
+ module Request
9
+ DEFAULT_HEADERS = {
10
+ "User-Agent" => "#{AppleClassClient.user_agent}/#{AppleClassClient::VERSION}",
11
+ "X-Server-Protocol-Version" => "2",
12
+ "Content-Type" => "application/json;charset=UTF8",
13
+ }
14
+ DEFAULT_HEADERS.freeze
15
+
16
+ def self.make_request(url, query_type, body, params:nil, headers:nil)
17
+ if headers == nil
18
+ headers = make_headers
19
+ end
20
+ request = Typhoeus::Request.new(
21
+ url,
22
+ method: query_type,
23
+ body: body,
24
+ params: params,
25
+ headers: headers,
26
+ )
27
+ request.run
28
+ AppleClassClient::Error.check_request_error request.response
29
+ JSON.parse request.response.body
30
+ end
31
+
32
+ def self.make_headers
33
+ session_auth_token = AppleClassClient::Auth.get_session_token
34
+ DEFAULT_HEADERS.merge("X-ADM-Auth-Session" => session_auth_token)
35
+ end
36
+
37
+ def self.make_url(path)
38
+ AppleClassClient.apple_mdm_server + path
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module AppleClassClient
2
- VERSION = "0.0.0"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,15 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apple_class_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Albert Wang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-15 00:00:00.000000000 Z
11
+ date: 2017-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: typhoeus
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.7'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '1.2'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0.7'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.2'
13
47
  - !ruby/object:Gem::Dependency
14
48
  name: bundler
15
49
  requirement: !ruby/object:Gem::Requirement
@@ -28,16 +62,16 @@ dependencies:
28
62
  name: rake
29
63
  requirement: !ruby/object:Gem::Requirement
30
64
  requirements:
31
- - - "~>"
65
+ - - ">="
32
66
  - !ruby/object:Gem::Version
33
- version: '10.0'
67
+ version: '11.0'
34
68
  type: :development
35
69
  prerelease: false
36
70
  version_requirements: !ruby/object:Gem::Requirement
37
71
  requirements:
38
- - - "~>"
72
+ - - ">="
39
73
  - !ruby/object:Gem::Version
40
- version: '10.0'
74
+ version: '11.0'
41
75
  - !ruby/object:Gem::Dependency
42
76
  name: rspec
43
77
  requirement: !ruby/object:Gem::Requirement
@@ -55,7 +89,7 @@ dependencies:
55
89
  description: This is a client for accessing Apple MDM's class, person, location, and
56
90
  course rosters.
57
91
  email:
58
- - albert@cellabus.com
92
+ - aywang31@gmail.com
59
93
  executables: []
60
94
  extensions: []
61
95
  extra_rdoc_files: []
@@ -71,6 +105,11 @@ files:
71
105
  - bin/console
72
106
  - bin/setup
73
107
  - lib/apple_class_client.rb
108
+ - lib/apple_class_client/auth.rb
109
+ - lib/apple_class_client/configuration.rb
110
+ - lib/apple_class_client/error.rb
111
+ - lib/apple_class_client/hacks/typhoeus_request.rb
112
+ - lib/apple_class_client/request.rb
74
113
  - lib/apple_class_client/version.rb
75
114
  homepage: https://github.com/albertyw/apple_class_client
76
115
  licenses: