chook 1.0.0.b1

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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +174 -0
  3. data/README.md +259 -0
  4. data/bin/chook-server +28 -0
  5. data/data/sample_handlers/RestAPIOperation-executable +91 -0
  6. data/data/sample_handlers/RestAPIOperation.rb +45 -0
  7. data/data/sample_handlers/SmartGroupComputerMembershipChange-executable +47 -0
  8. data/data/sample_handlers/SmartGroupComputerMembershipChange.rb +33 -0
  9. data/data/sample_jsons/ComputerAdded.json +27 -0
  10. data/data/sample_jsons/ComputerCheckIn.json +27 -0
  11. data/data/sample_jsons/ComputerInventoryCompleted.json +27 -0
  12. data/data/sample_jsons/ComputerPolicyFinished.json +27 -0
  13. data/data/sample_jsons/ComputerPushCapabilityChanged.json +27 -0
  14. data/data/sample_jsons/JSSShutdown.json +14 -0
  15. data/data/sample_jsons/JSSStartup.json +14 -0
  16. data/data/sample_jsons/MobileDeviceCheckIn.json +26 -0
  17. data/data/sample_jsons/MobileDeviceCommandCompleted.json +26 -0
  18. data/data/sample_jsons/MobileDeviceEnrolled.json +26 -0
  19. data/data/sample_jsons/MobileDevicePushSent.json +26 -0
  20. data/data/sample_jsons/MobileDeviceUnEnrolled.json +26 -0
  21. data/data/sample_jsons/PatchSoftwareTitleUpdated.json +14 -0
  22. data/data/sample_jsons/PushSent.json +11 -0
  23. data/data/sample_jsons/README +4 -0
  24. data/data/sample_jsons/RestAPIOperation.json +15 -0
  25. data/data/sample_jsons/SCEPChallenge.json +10 -0
  26. data/data/sample_jsons/SmartGroupComputerMembershipChange.json +13 -0
  27. data/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +13 -0
  28. data/lib/chook.rb +38 -0
  29. data/lib/chook/configuration.rb +198 -0
  30. data/lib/chook/event.rb +153 -0
  31. data/lib/chook/event/handled_event.rb +154 -0
  32. data/lib/chook/event/handled_event/handlers.rb +206 -0
  33. data/lib/chook/event/test_event.rb +140 -0
  34. data/lib/chook/event_handling.rb +40 -0
  35. data/lib/chook/event_testing.rb +43 -0
  36. data/lib/chook/foundation.rb +33 -0
  37. data/lib/chook/handled_events.rb +33 -0
  38. data/lib/chook/handled_subjects.rb +33 -0
  39. data/lib/chook/procs.rb +46 -0
  40. data/lib/chook/server.rb +121 -0
  41. data/lib/chook/server/routes.rb +27 -0
  42. data/lib/chook/server/routes/handle_webhook_event.rb +39 -0
  43. data/lib/chook/server/routes/home.rb +37 -0
  44. data/lib/chook/subject.rb +143 -0
  45. data/lib/chook/subject/computer.rb +121 -0
  46. data/lib/chook/subject/handled_subject.rb +84 -0
  47. data/lib/chook/subject/jss.rb +56 -0
  48. data/lib/chook/subject/mobile_device.rb +115 -0
  49. data/lib/chook/subject/patch_software_title_update.rb +55 -0
  50. data/lib/chook/subject/push.rb +38 -0
  51. data/lib/chook/subject/randomizers.rb +506 -0
  52. data/lib/chook/subject/rest_api_operation.rb +62 -0
  53. data/lib/chook/subject/samplers.rb +360 -0
  54. data/lib/chook/subject/scep_challenge.rb +32 -0
  55. data/lib/chook/subject/smart_group.rb +50 -0
  56. data/lib/chook/subject/test_subject.rb +195 -0
  57. data/lib/chook/subject/validators.rb +117 -0
  58. data/lib/chook/test_events.rb +33 -0
  59. data/lib/chook/test_subjects.rb +33 -0
  60. data/lib/chook/version.rb +32 -0
  61. metadata +129 -0
@@ -0,0 +1,50 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+ Chook::Subject.classes[Chook::Subject::SMART_GROUP] = {
26
+ name: {
27
+ validation: String,
28
+ randomizer: :word,
29
+ # sampler: :smart_group,
30
+ api_object_attribute: :name
31
+ },
32
+ smartGroup: {
33
+ validation: :boolean,
34
+ randomizer: Chook::Procs::ALWAYS_TRUE, # If this were false, it wouldn't be a Smart Group...
35
+ # sampler: Chook::Procs::ALWAYS_TRUE,
36
+ api_object_attribute: :is_smart
37
+ },
38
+ jssid: {
39
+ validation: Integer,
40
+ randomizer: :int,
41
+ # sampler: :smart_group_jssid,
42
+ api_object_attribute: :id
43
+ },
44
+ computer: { # SmartGroupComputerMembershipChange == true, SmartGroupMobileDeviceMembershipChange == false
45
+ validation: :boolean,
46
+ randomizer: :bool,
47
+ # sampler: ,
48
+ # api_object_attribute: :computer
49
+ }
50
+ }
@@ -0,0 +1,195 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ module Chook
27
+
28
+ # A subject that will be used with a TestEvent class, to be sent to
29
+ # a Webhook server, simulating one from the JSS.
30
+ #
31
+ # This is the parent class to all classes in the Chook::TestSubjects module.
32
+ #
33
+ # All constants, methods, and attributes that are common to TestSubject
34
+ # classes are defined here.
35
+ #
36
+ class TestSubject < Chook::Subject
37
+
38
+ # Dynamically generate the varios subclasses to TestSubject
39
+ # and store them in the TestSubjects module.
40
+ def self.generate_classes
41
+ Chook::Subject.classes.each do |classname, attribs|
42
+ # Don't redefine anything.
43
+ next if Chook::TestSubjects.const_defined? classname
44
+
45
+ # new subclass of Chook::TestSubject
46
+ new_class = Class.new(Chook::TestSubject) do
47
+ # add getter, setters, validators for all the attribs.
48
+ attribs.each do |attrib, deets|
49
+ # getter
50
+ attr_reader attrib
51
+ validator = deets[:validation]
52
+
53
+ # setter with validator
54
+ define_method("#{attrib}=") do |new_val|
55
+ if validator.is_a? Class
56
+ raise "Invalid value for #{attrib}, must be a #{validator}" unless new_val.is_a? validator
57
+ elsif !validator.nil?
58
+ raise "Invalid value for #{attrib}" unless Chook::Validators.send validator, new_val
59
+ end
60
+ instance_variable_set(('@' + attrib.to_s), new_val)
61
+ end # end define method
62
+ end # end do |attrib, deets|
63
+ end # end new_class
64
+ # set a class constant so each class knows it's name
65
+ new_class.const_set Chook::Subject::NAME_CONSTANT, classname
66
+
67
+ # add the class to the Chook::TestSubjects module
68
+ Chook::TestSubjects.const_set classname, new_class
69
+ end # end Chook::Subject.classes.each do |classname, attribs|
70
+ end # end generate_classes
71
+
72
+ # a random test subject,
73
+ def self.random
74
+ random_vals = {}
75
+ Chook::Subject.classes[].each do |attrib, deets|
76
+ random_vals[attrib] = Chook::Randomizers.send deets[:randomizer]
77
+ end # each do |attr_def|
78
+ new random_vals
79
+ end # end random
80
+
81
+ # a sampled test subject (real data from real JSS objects)
82
+ # NOTE: a valid ruby-jss JSS::APIConnection must exist
83
+ def self.sample(ids = 'random', api: JSS.api)
84
+ classname = self.const_get Chook::Subject::NAME_CONSTANT
85
+ ids = [ids] if ids.is_a? Integer
86
+ # !!Kernel.const_get('JSS::' + classname) rescue false
87
+ if classname == 'PatchSoftwareTitleUpdated'
88
+ all_ids = Chook::Samplers.all_patch_ids('blah', api: api)
89
+ else
90
+ all_ids = Kernel.const_get('JSS::' + classname).all_ids(api: api) # (api: api)
91
+ end
92
+ ids = [all_ids.sample] if ids == 'random'
93
+
94
+ ok = true
95
+ if ids.is_a? Array
96
+ ids.each { |id| ok == false unless id.is_a? Integer }
97
+ else
98
+ ok = false
99
+ end
100
+ raise 'ids must be an Array of Integers' unless ok
101
+
102
+ raw_samples = []
103
+ samples = []
104
+
105
+ valid_ids = ids & all_ids
106
+ raise "Invalid JSS IDs: #{ids}" if valid_ids.empty?
107
+
108
+ valid_ids.each do |id|
109
+ if classname == 'PatchSoftwareTitleUpdated'
110
+ raw_samples << Chook::Samplers.all_patches(api: api).select { |patch| patch[:id] == id }
111
+ raw_samples.flatten!
112
+ else
113
+ raw_samples << Kernel.const_get('JSS::' + classname).fetch(id: id, api: api)
114
+ end
115
+ end
116
+
117
+ raw_samples.each do |sample|
118
+ subject_details = {}
119
+ Chook::Subject.classes[classname].map do |subject_key, details|
120
+ extractor = details[:api_object_attribute]
121
+ subject_details[subject_key] =
122
+ case extractor
123
+ when Symbol
124
+ if classname == 'PatchSoftwareTitleUpdated'
125
+ # If there is a sampler method available, call it.
126
+ if details[:sampler]
127
+ extractor = details[:sampler]
128
+ Chook::Samplers.send(extractor, sample)
129
+ else
130
+ # Otherwise use it like a hash key
131
+ sample[extractor]
132
+ end
133
+ else
134
+ sample.send extractor
135
+ end
136
+ when Array
137
+ extractor = extractor.dup # If this doesn't get duplicated, shift will change details[:api_object_attribute]
138
+ method = extractor.shift
139
+ raw_hash_keys = extractor
140
+ method_result = sample.send(method)
141
+ raw_hash_keys.each { |key| method_result = method_result[key] }
142
+ method_result
143
+ when Proc
144
+ extractor.call sample
145
+ end
146
+ end # do |subject_key, details|
147
+ samples << Kernel.const_get('Chook::TestSubjects::' + classname).new(subject_details)
148
+ end # end samples.each do |sample|
149
+ samples
150
+ end # end sample
151
+
152
+ def json_hash
153
+ # Verify that input is a child of TestSubjects, raise if not
154
+ raise 'Invalid TestSubject' unless self.class.superclass == Chook::TestSubject
155
+ test_subject_attributes = Chook::Subject.classes[self.class.to_s.split('::')[-1]]
156
+ raw_hash_form = {}
157
+ test_subject_attributes.each do |attribute, details|
158
+ if details.keys.include? :to_json
159
+ raw_hash_form[attribute] = send(attribute).send details[:to_json]
160
+ else
161
+ raw_hash_form[attribute] = instance_variable_get('@' + attribute.to_s)
162
+ end
163
+ end # end test_subject_attributes.keys.each do |attribute, details|
164
+ raw_hash_form
165
+ end # end json_hash
166
+
167
+ # All the subclassses will inherit this constructor
168
+ #
169
+ # The argument is a Hash with keys from the appropriate keys defiend
170
+ # in Chook::Subject.classes
171
+ #
172
+ def initialize(subject_data = nil)
173
+ classname = self.class.const_get Chook::Subject::NAME_CONSTANT
174
+ attribs = Chook::Subject.classes[classname]
175
+
176
+ if subject_data
177
+ subject_data.each do |key, value|
178
+ # ignore unknown attributes. Shouldn't get any, but...
179
+ next unless attribs[key]
180
+
181
+ # does the value need conversion?
182
+ converter = attribs[key][:converter]
183
+ if converter
184
+ value = converter.is_a?(Symbol) ? value.send(converter) : converter.call(value)
185
+ end # if converter
186
+ instance_variable_set(('@' + key.to_s), value)
187
+ end # each key value
188
+ else
189
+ attribs.keys.each { |key| instance_variable_set(('@' + key.to_s), nil) }
190
+ end # if subject_data
191
+ end # init
192
+
193
+ end # class TestSubject
194
+
195
+ end # module
@@ -0,0 +1,117 @@
1
+ require 'uri'
2
+
3
+ module Chook
4
+
5
+ # A namespace to hold validation methods for use with
6
+ # Test Events and Test Subjects.
7
+ # Each method taks a value, and returns a boolean
8
+ # indicating the validity of the value.
9
+ #
10
+ module Validators
11
+
12
+ # Validate MAC Address
13
+ #
14
+ # @param [String] MAC address formatted String
15
+ # @return [Boolean]
16
+ #
17
+ def self.mac_address(mac)
18
+ mac =~ /^([a-f\d]{2}:){5}[a-f\d]{2}$/i ? true : false
19
+ end # end mac_address
20
+
21
+ # Validate E-mail Address
22
+ #
23
+ # @param [String] E-mail address formatted String e.g. FirstNameLastName@randomword.com
24
+ # @return [Boolean]
25
+ #
26
+ def self.email(email_address)
27
+ email_address =~ /^[a-zA-Z]([\w -]*[a-zA-Z])\@\w*\.\w*$/ ? true : false
28
+ end # end email
29
+
30
+ # Validate URL
31
+ #
32
+ # @param [String] URL formatted String
33
+ # @return [Boolean]
34
+ #
35
+ def self.url(url)
36
+ uri = URI.parse(url)
37
+ uri.is_a?(URI::HTTP) && !uri.host.nil? ? true : false
38
+ end # end url
39
+
40
+ # Validate Serial Number
41
+ #
42
+ # @param [String] Serial Number Formatted String
43
+ # @return [Boolean]
44
+ #
45
+ def self.serial_number(serial)
46
+ raise TypeError unless serial.is_a? String
47
+ serial_array = serial.scan(/\w/)
48
+ return false if serial.empty?
49
+ serial_array.each_with_index do |character, index|
50
+ return false unless (Chook::Randomizers::MOBILE_SERIAL_CHARACTER_SETS[index].include? character) || (Chook::Randomizers::COMPUTER_SERIAL_CHARACTER_SETS[index].include? character)
51
+ end
52
+ true
53
+ end # end serial_number
54
+
55
+ # Validate Push
56
+ #
57
+ # @param [String] Push Type
58
+ # @return [Boolean]
59
+ #
60
+ def self.push(push)
61
+ raise TypeError unless push.is_a? String
62
+ return false if push.empty?
63
+ return false unless Chook::Randomizers::PUSH_COMMANDS.include? push
64
+ true
65
+ end # end push
66
+
67
+ # Validate IMEI
68
+ #
69
+ # @param [String] A 17-15 digit sequence of numbers
70
+ # @return [Boolean]
71
+ #
72
+ def self.imei(imei)
73
+ imei_length = imei.delete(' ').size
74
+ (15...17).cover? imei_length
75
+ end # end imei
76
+
77
+ # Validate ICCID
78
+ #
79
+ # @param [String] ICCID
80
+ # @return [Boolean]
81
+ #
82
+ def self.iccid(iccid)
83
+ iccid_length = iccid.delete(' ').size
84
+ return true if iccid_length < 23
85
+ end # end iccid
86
+
87
+ # Validate Boolean
88
+ #
89
+ # @param [Boolean] Make sure input is valid Boolean, because Ruby doesn't have a Boolean Class
90
+ # @return [Boolean]
91
+ #
92
+ def self.boolean(true_or_false)
93
+ [true, false].include? true_or_false
94
+ end # end boolean
95
+
96
+ # Validate Patch
97
+ #
98
+ # @param [String] Name of a Patch Reporting Software Title
99
+ # @return [Boolean]
100
+ #
101
+ def self.patch(patch_name)
102
+ Chook::Randomizers::PATCH_SOFTWARE_TITLES.include? patch_name
103
+ end # end patch
104
+
105
+ # Validate Test Subject
106
+ #
107
+ # @param [String] Name of an Event class
108
+ # @param [Chook::TestSubjects] An instance of a Chook::TestSubjects subclass
109
+ # @return [Boolean]
110
+ #
111
+ def self.valid_test_subject(event_class, subject)
112
+ Chook::Event::EVENTS[event_class].include? subject.class.to_s.split('::')[-1]
113
+ end # end valid_test_subject
114
+
115
+ end # module validators
116
+
117
+ end # module Chook
@@ -0,0 +1,33 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ module Chook
27
+
28
+ # This class is a namespace holding all of the classes that are
29
+ # subclasses of Chook::TestEvent, q.v.
30
+ #
31
+ class TestEvents; end # class TestEvents
32
+
33
+ end # class Chook
@@ -0,0 +1,33 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ module Chook
27
+
28
+ # This module is a namespace holding all of the classes that are
29
+ # subclasses of Chook::TestSubject, q.v.
30
+ #
31
+ module TestSubjects; end # module TestSubjects
32
+
33
+ end # module
@@ -0,0 +1,32 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ ###
27
+ module Chook
28
+
29
+ ### The version of the Chook framework
30
+ VERSION = '1.0.0.b1'.freeze
31
+
32
+ end # module