chook 1.0.0.b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +174 -0
- data/README.md +259 -0
- data/bin/chook-server +28 -0
- data/data/sample_handlers/RestAPIOperation-executable +91 -0
- data/data/sample_handlers/RestAPIOperation.rb +45 -0
- data/data/sample_handlers/SmartGroupComputerMembershipChange-executable +47 -0
- data/data/sample_handlers/SmartGroupComputerMembershipChange.rb +33 -0
- data/data/sample_jsons/ComputerAdded.json +27 -0
- data/data/sample_jsons/ComputerCheckIn.json +27 -0
- data/data/sample_jsons/ComputerInventoryCompleted.json +27 -0
- data/data/sample_jsons/ComputerPolicyFinished.json +27 -0
- data/data/sample_jsons/ComputerPushCapabilityChanged.json +27 -0
- data/data/sample_jsons/JSSShutdown.json +14 -0
- data/data/sample_jsons/JSSStartup.json +14 -0
- data/data/sample_jsons/MobileDeviceCheckIn.json +26 -0
- data/data/sample_jsons/MobileDeviceCommandCompleted.json +26 -0
- data/data/sample_jsons/MobileDeviceEnrolled.json +26 -0
- data/data/sample_jsons/MobileDevicePushSent.json +26 -0
- data/data/sample_jsons/MobileDeviceUnEnrolled.json +26 -0
- data/data/sample_jsons/PatchSoftwareTitleUpdated.json +14 -0
- data/data/sample_jsons/PushSent.json +11 -0
- data/data/sample_jsons/README +4 -0
- data/data/sample_jsons/RestAPIOperation.json +15 -0
- data/data/sample_jsons/SCEPChallenge.json +10 -0
- data/data/sample_jsons/SmartGroupComputerMembershipChange.json +13 -0
- data/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +13 -0
- data/lib/chook.rb +38 -0
- data/lib/chook/configuration.rb +198 -0
- data/lib/chook/event.rb +153 -0
- data/lib/chook/event/handled_event.rb +154 -0
- data/lib/chook/event/handled_event/handlers.rb +206 -0
- data/lib/chook/event/test_event.rb +140 -0
- data/lib/chook/event_handling.rb +40 -0
- data/lib/chook/event_testing.rb +43 -0
- data/lib/chook/foundation.rb +33 -0
- data/lib/chook/handled_events.rb +33 -0
- data/lib/chook/handled_subjects.rb +33 -0
- data/lib/chook/procs.rb +46 -0
- data/lib/chook/server.rb +121 -0
- data/lib/chook/server/routes.rb +27 -0
- data/lib/chook/server/routes/handle_webhook_event.rb +39 -0
- data/lib/chook/server/routes/home.rb +37 -0
- data/lib/chook/subject.rb +143 -0
- data/lib/chook/subject/computer.rb +121 -0
- data/lib/chook/subject/handled_subject.rb +84 -0
- data/lib/chook/subject/jss.rb +56 -0
- data/lib/chook/subject/mobile_device.rb +115 -0
- data/lib/chook/subject/patch_software_title_update.rb +55 -0
- data/lib/chook/subject/push.rb +38 -0
- data/lib/chook/subject/randomizers.rb +506 -0
- data/lib/chook/subject/rest_api_operation.rb +62 -0
- data/lib/chook/subject/samplers.rb +360 -0
- data/lib/chook/subject/scep_challenge.rb +32 -0
- data/lib/chook/subject/smart_group.rb +50 -0
- data/lib/chook/subject/test_subject.rb +195 -0
- data/lib/chook/subject/validators.rb +117 -0
- data/lib/chook/test_events.rb +33 -0
- data/lib/chook/test_subjects.rb +33 -0
- data/lib/chook/version.rb +32 -0
- metadata +129 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"webhook": {
|
3
|
+
"id": 11,
|
4
|
+
"name": "MobileEnrolled Webhook",
|
5
|
+
"webhookEvent": "MobileDeviceEnrolled"
|
6
|
+
},
|
7
|
+
"event": {
|
8
|
+
"udid": "0d12c74062dxyxyxb4b234f4ac1yxyxyx1efccd0",
|
9
|
+
"deviceName": "tipple",
|
10
|
+
"version": "4.71.00",
|
11
|
+
"model": "iPhone7,2",
|
12
|
+
"bluetoothMacAddress": "xx:xx:37:yy:78:xx",
|
13
|
+
"wifiMacAddress": "yy:yy:37:xx:78:yy",
|
14
|
+
"imei": "xx yyyyyy zzzzzz 0",
|
15
|
+
"icciID": "aaaa bbbb cccc dddd eeee",
|
16
|
+
"product": null,
|
17
|
+
"serialNumber": "C8EM25KSG5PT",
|
18
|
+
"userDirectoryID": "-1",
|
19
|
+
"room": "s167",
|
20
|
+
"osVersion": "9.3.4",
|
21
|
+
"osBuild": "13G35",
|
22
|
+
"modelDisplay": "iPhone 6",
|
23
|
+
"username": "username",
|
24
|
+
"jssID": 158
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"webhook": {
|
3
|
+
"id": 12,
|
4
|
+
"name": "MobilePush Webhook",
|
5
|
+
"webhookEvent": "MobileDevicePushSent"
|
6
|
+
},
|
7
|
+
"event": {
|
8
|
+
"udid": "0d12c74062dxyxyxb4b234f4ac1yxyxyx1efccd0",
|
9
|
+
"deviceName": "tipple",
|
10
|
+
"version": "4.71.00",
|
11
|
+
"model": "iPhone7,2",
|
12
|
+
"bluetoothMacAddress": "xx:xx:37:yy:78:xx",
|
13
|
+
"wifiMacAddress": "yy:yy:37:xx:78:yy",
|
14
|
+
"imei": "xx yyyyyy zzzzzz 0",
|
15
|
+
"icciID": "aaaa bbbb cccc dddd eeee",
|
16
|
+
"product": null,
|
17
|
+
"serialNumber": "C8EM25KSG5PT",
|
18
|
+
"userDirectoryID": "-1",
|
19
|
+
"room": "s167",
|
20
|
+
"osVersion": "9.3.4",
|
21
|
+
"osBuild": "13G35",
|
22
|
+
"modelDisplay": "iPhone 6",
|
23
|
+
"username": "username",
|
24
|
+
"jssID": 158
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"webhook": {
|
3
|
+
"id": 13,
|
4
|
+
"name": "MobileUnEnrolled Webhook",
|
5
|
+
"webhookEvent": "MobileDeviceUnEnrolled"
|
6
|
+
},
|
7
|
+
"event": {
|
8
|
+
"udid": "0d12c74062dxyxyxb4b234f4ac1yxyxyx1efccd0",
|
9
|
+
"deviceName": "tipple",
|
10
|
+
"version": "4.71.00",
|
11
|
+
"model": "iPhone7,2",
|
12
|
+
"bluetoothMacAddress": "xx:xx:37:yy:78:xx",
|
13
|
+
"wifiMacAddress": "yy:yy:37:xx:78:yy",
|
14
|
+
"imei": "xx yyyyyy zzzzzz 0",
|
15
|
+
"icciID": "aaaa bbbb cccc dddd eeee",
|
16
|
+
"product": null,
|
17
|
+
"serialNumber": "C8EM25KSG5PT",
|
18
|
+
"userDirectoryID": "-1",
|
19
|
+
"room": "s167",
|
20
|
+
"osVersion": "9.3.4",
|
21
|
+
"osBuild": "13G35",
|
22
|
+
"modelDisplay": "iPhone 6",
|
23
|
+
"username": "username",
|
24
|
+
"jssID": 158
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"webhook": {
|
3
|
+
"id": 14,
|
4
|
+
"name": "PatchSoftwareTitleUpdated Webhook",
|
5
|
+
"webhookEvent": "PatchSoftwareTitleUpdated"
|
6
|
+
},
|
7
|
+
"event": {
|
8
|
+
"name": "CoolApp",
|
9
|
+
"latestVersion": "12.4.3",
|
10
|
+
"lastUpdate": 1463054400000,
|
11
|
+
"reportUrl": "http://CoolApp.com/downloads/latest",
|
12
|
+
"jssID": 1
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"webhook": {
|
3
|
+
"id": 16,
|
4
|
+
"name": "RestAPIOperation Webhook",
|
5
|
+
"webhookEvent": "RestAPIOperation"
|
6
|
+
},
|
7
|
+
"event": {
|
8
|
+
"operationSuccessful": true,
|
9
|
+
"objectID": 1233,
|
10
|
+
"objectName": "wanderer",
|
11
|
+
"objectTypeName": "computer",
|
12
|
+
"authorizedUsername": "username",
|
13
|
+
"restAPIOperationType": "POST"
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"webhook": {
|
3
|
+
"id": 19,
|
4
|
+
"name": "SmartGroupMobileDeviceMembershipChange Webhook",
|
5
|
+
"webhookEvent": "SmartGroupMobileDeviceMembershipChange"
|
6
|
+
},
|
7
|
+
"event": {
|
8
|
+
"name": "OddMobileDevs",
|
9
|
+
"smartGroup": true,
|
10
|
+
"jssid": 99,
|
11
|
+
"computer": false
|
12
|
+
}
|
13
|
+
}
|
data/lib/chook.rb
ADDED
@@ -0,0 +1,38 @@
|
|
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
|
+
# Requiring this file (require 'chook') will load the entire library
|
27
|
+
# including event testing, event handling, and the server.
|
28
|
+
#
|
29
|
+
# To load a subset, use one of:
|
30
|
+
# require 'chook/event_testing'
|
31
|
+
# require 'chook/event_handing'
|
32
|
+
# require 'chook/server'
|
33
|
+
|
34
|
+
require 'chook/foundation'
|
35
|
+
require 'chook/event_testing'
|
36
|
+
|
37
|
+
# the server - it loads the event handling files
|
38
|
+
require 'chook/server'
|
@@ -0,0 +1,198 @@
|
|
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
|
+
require 'singleton'
|
27
|
+
|
28
|
+
module Chook
|
29
|
+
|
30
|
+
# The configuration object
|
31
|
+
class Configuration
|
32
|
+
|
33
|
+
include ::Singleton
|
34
|
+
|
35
|
+
# The location of the default config file
|
36
|
+
DEFAULT_CONF_FILE = Pathname.new '/etc/chook.conf'
|
37
|
+
|
38
|
+
# The attribute keys we maintain, and the type they should be stored as
|
39
|
+
CONF_KEYS = {
|
40
|
+
server_port: :to_i,
|
41
|
+
server_engine: :to_sym,
|
42
|
+
handler_dir: nil,
|
43
|
+
use_ssl: Chook::Procs::STRING_TO_BOOLEAN,
|
44
|
+
ssl_private_key_path: Chook::Procs::STRING_TO_PATHNAME,
|
45
|
+
ssl_private_key_pw_path: nil,
|
46
|
+
ssl_cert_path: Chook::Procs::STRING_TO_PATHNAME,
|
47
|
+
ssl_cert_name: nil
|
48
|
+
}.freeze
|
49
|
+
|
50
|
+
# Class Variables
|
51
|
+
#####################################
|
52
|
+
|
53
|
+
# Class Methods
|
54
|
+
#####################################
|
55
|
+
|
56
|
+
# Attributes
|
57
|
+
#####################################
|
58
|
+
|
59
|
+
# automatically create accessors for all the CONF_KEYS
|
60
|
+
CONF_KEYS.keys.each { |k| attr_accessor k }
|
61
|
+
|
62
|
+
# Constructor
|
63
|
+
#####################################
|
64
|
+
|
65
|
+
# Initialize!
|
66
|
+
#
|
67
|
+
def initialize
|
68
|
+
read_global
|
69
|
+
end
|
70
|
+
|
71
|
+
# Public Instance Methods
|
72
|
+
#####################################
|
73
|
+
|
74
|
+
# Clear all values
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
#
|
78
|
+
def clear_all
|
79
|
+
CONF_KEYS.keys.each { |k| send "#{k}=".to_sym, nil }
|
80
|
+
end
|
81
|
+
|
82
|
+
# (Re)read the global prefs, if it exists.
|
83
|
+
#
|
84
|
+
# @return [Boolean] was the file loaded?
|
85
|
+
#
|
86
|
+
def read_global
|
87
|
+
return false unless DEFAULT_CONF_FILE.file? && DEFAULT_CONF_FILE.readable?
|
88
|
+
read DEFAULT_CONF_FILE
|
89
|
+
end
|
90
|
+
|
91
|
+
# Clear the settings and reload the prefs file, or another file if provided
|
92
|
+
#
|
93
|
+
# @param file[String,Pathname] a non-standard prefs file to load
|
94
|
+
#
|
95
|
+
# @return [Boolean] was the file reloaded?
|
96
|
+
#
|
97
|
+
def reload(file = DEFAULT_CONF_FILE)
|
98
|
+
file = Pathname.new file
|
99
|
+
return false unless file.file? && file.readable?
|
100
|
+
clear_all
|
101
|
+
read file
|
102
|
+
end
|
103
|
+
|
104
|
+
# Save the prefs into a file
|
105
|
+
#
|
106
|
+
# @param file[Symbol,String,Pathname] either :user, :global, or an arbitrary file to save.
|
107
|
+
#
|
108
|
+
# @return [void]
|
109
|
+
#
|
110
|
+
def save(file)
|
111
|
+
path = Pathname.new(file)
|
112
|
+
|
113
|
+
# file already exists? read it in and update the values.
|
114
|
+
# Don't overwrite it, since the user might have comments
|
115
|
+
# in there.
|
116
|
+
if path.readable?
|
117
|
+
data = path.read
|
118
|
+
|
119
|
+
# go thru the known attributes/keys
|
120
|
+
CONF_KEYS.keys.sort.each do |k|
|
121
|
+
# if the key exists, update it.
|
122
|
+
if data =~ /^#{k}:/
|
123
|
+
data.sub!(/^#{k}:.*$/, "#{k}: #{send k}")
|
124
|
+
|
125
|
+
# if not, add it to the end unless it's nil
|
126
|
+
else
|
127
|
+
data += "\n#{k}: #{send k}" unless send(k).nil?
|
128
|
+
end # if data =~ /^#{k}:/
|
129
|
+
end # each do |k|
|
130
|
+
|
131
|
+
else # not readable, make a new file
|
132
|
+
data = ''
|
133
|
+
CONF_KEYS.keys.sort.each do |k|
|
134
|
+
data << "#{k}: #{send k}\n" unless send(k).nil?
|
135
|
+
end
|
136
|
+
end # if path readable
|
137
|
+
|
138
|
+
# make sure we end with a newline, the save it.
|
139
|
+
data << "\n" unless data.end_with?("\n")
|
140
|
+
path.open('w') { |f| f.write data }
|
141
|
+
end # save file
|
142
|
+
|
143
|
+
# Print out the current settings to stdout
|
144
|
+
#
|
145
|
+
# @return [void]
|
146
|
+
#
|
147
|
+
def print
|
148
|
+
CONF_KEYS.keys.sort.each { |k| puts "#{k}: #{send k}" }
|
149
|
+
end
|
150
|
+
|
151
|
+
# Private Instance Methods
|
152
|
+
#####################################
|
153
|
+
private
|
154
|
+
|
155
|
+
# Read in a prefs file
|
156
|
+
#
|
157
|
+
# @param file[String,Pathname] the file to read
|
158
|
+
#
|
159
|
+
# @return [Boolean] was the file read?
|
160
|
+
#
|
161
|
+
def read(file)
|
162
|
+
available_conf_keys = CONF_KEYS.keys
|
163
|
+
Pathname.new(file).read.each_line do |line|
|
164
|
+
# skip blank lines and those starting with #
|
165
|
+
next if line =~ /^\s*(#|$)/
|
166
|
+
|
167
|
+
line.strip =~ /^(\w+?):\s*(\S.*)$/
|
168
|
+
key = Regexp.last_match(1)
|
169
|
+
next unless key
|
170
|
+
attr = key.to_sym
|
171
|
+
next unless available_conf_keys.include? attr
|
172
|
+
setter = "#{key}=".to_sym
|
173
|
+
value = Regexp.last_match(2).strip
|
174
|
+
|
175
|
+
# convert the string value read from the file
|
176
|
+
# to the correct class
|
177
|
+
value &&= case CONF_KEYS[attr]
|
178
|
+
when Proc
|
179
|
+
# If its a proc, pass it to the proc
|
180
|
+
CONF_KEYS[attr].call value
|
181
|
+
when Symbol
|
182
|
+
# otherwise its a symbol method name to call on the string
|
183
|
+
value.send(CONF_KEYS[attr])
|
184
|
+
else
|
185
|
+
value
|
186
|
+
end
|
187
|
+
|
188
|
+
send(setter, value)
|
189
|
+
end # do line
|
190
|
+
true
|
191
|
+
end # read file
|
192
|
+
|
193
|
+
end # class Configuration
|
194
|
+
|
195
|
+
# The single instance of Configuration
|
196
|
+
CONFIG = Chook::Configuration.instance
|
197
|
+
|
198
|
+
end # module
|
data/lib/chook/event.rb
ADDED
@@ -0,0 +1,153 @@
|
|
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
|
+
# This is the MetaClass for all Event objects, both handled and test.
|
30
|
+
# It holds constants, methods, and attributes that are common to all
|
31
|
+
# events in Chook.
|
32
|
+
#
|
33
|
+
# An 'event' within Chook is the ruby-abstraction of a JSON payload
|
34
|
+
# as sent by a JSS Webhook representing an event that takes place in the JSS.
|
35
|
+
#
|
36
|
+
# All events contain a #subject attribute, which represent the thing
|
37
|
+
# upon which the event acted, e.g. a computer, mobile divice, or the
|
38
|
+
# JSS itself.
|
39
|
+
# The #subject attribute contains an object which is a subclass
|
40
|
+
# of Chook::Subject, q.v.
|
41
|
+
#
|
42
|
+
class Event
|
43
|
+
|
44
|
+
# A mapping of the Event Names (as they are known to the JSS)
|
45
|
+
# to the the matching Subject class names
|
46
|
+
#
|
47
|
+
# The event names from the JSS are in the JSON hash as the value of
|
48
|
+
# JSON_hash[:webhook][:webhookEvent] and they are also the names
|
49
|
+
# of the matching event classes within the HandledEvent module and the
|
50
|
+
# TestEvent module.
|
51
|
+
#
|
52
|
+
# E.g.
|
53
|
+
# the HandledEvents class that handles the 'ComputerPolicyFinished'
|
54
|
+
# event is Chook::HandledEvent::ComputerPolicyFinished
|
55
|
+
#
|
56
|
+
# and
|
57
|
+
#
|
58
|
+
# the TestEvents that simulates 'ComputerPolicyFinished' is
|
59
|
+
# Chook::TestEvents::ComputerPolicyFinished
|
60
|
+
#
|
61
|
+
# And, those classes take the matching 'Computer' subject, either
|
62
|
+
# Chook::HandledSubjects::Computer or Chook::TestSubjects::Computer
|
63
|
+
#
|
64
|
+
EVENTS = {
|
65
|
+
'ComputerAdded' => Chook::Subject::COMPUTER,
|
66
|
+
'ComputerCheckIn' => Chook::Subject::COMPUTER,
|
67
|
+
'ComputerInventoryCompleted' => Chook::Subject::COMPUTER,
|
68
|
+
'ComputerPolicyFinished' => Chook::Subject::COMPUTER,
|
69
|
+
'ComputerPushCapabilityChanged' => Chook::Subject::COMPUTER,
|
70
|
+
'JSSShutdown' => Chook::Subject::JAMF_SOFTWARE_SERVER,
|
71
|
+
'JSSStartup' => Chook::Subject::JAMF_SOFTWARE_SERVER,
|
72
|
+
'MobileDeviceCheckIn' => Chook::Subject::MOBILE_DEVICE,
|
73
|
+
'MobileDeviceCommandCompleted' => Chook::Subject::MOBILE_DEVICE,
|
74
|
+
'MobileDeviceEnrolled' => Chook::Subject::MOBILE_DEVICE,
|
75
|
+
'MobileDevicePushSent' => Chook::Subject::MOBILE_DEVICE,
|
76
|
+
'MobileDeviceUnEnrolled' => Chook::Subject::MOBILE_DEVICE,
|
77
|
+
'PatchSoftwareTitleUpdated' => Chook::Subject::PATCH_SW_UPDATE,
|
78
|
+
'PushSent' => Chook::Subject::PUSH,
|
79
|
+
'RestAPIOperation' => Chook::Subject::REST_API_OPERATION,
|
80
|
+
'SCEPChallenge' => Chook::Subject::SCEP_CHALLENGE,
|
81
|
+
'SmartGroupComputerMembershipChange' => Chook::Subject::SMART_GROUP,
|
82
|
+
'SmartGroupMobileDeviceMembershipChange' => Chook::Subject::SMART_GROUP
|
83
|
+
}.freeze
|
84
|
+
|
85
|
+
# Event subclasses will have an EVENT_NAME constant,
|
86
|
+
# which contains the name of the event, one of the keys
|
87
|
+
# from the Event::EVENTS Hash.
|
88
|
+
EVENT_NAME_CONST = 'EVENT_NAME'.freeze
|
89
|
+
|
90
|
+
# Event subclasses will have a SUBJECT_CLASS constant,
|
91
|
+
# which contains the class of the subject of the event, based on one of the
|
92
|
+
# values from the Event::EVENTS Hash.
|
93
|
+
SUBJECT_CLASS_CONST = 'SUBJECT_CLASS'.freeze
|
94
|
+
|
95
|
+
#### Attrbutes common to all events
|
96
|
+
|
97
|
+
# @return [Integer] The webhook id in the JSS that caused this event
|
98
|
+
attr_reader :webhook_id
|
99
|
+
|
100
|
+
# @return [String] The webhook name in the JSS that caused this event
|
101
|
+
attr_reader :webhook_name
|
102
|
+
|
103
|
+
# @return [Object] The subject of this event - i.e. the thing it acted upon.
|
104
|
+
# An instance of a class from either the Chook::HandledSubjects module
|
105
|
+
# or the Chook::TestSubjects module
|
106
|
+
attr_reader :subject
|
107
|
+
|
108
|
+
# @return [String, nil] If this event object was initialized with a JSON
|
109
|
+
# blob as from the JSS, it will be stored here.
|
110
|
+
attr_reader :raw_json
|
111
|
+
|
112
|
+
# @return [Hash, nil] If this event object was initialized with a JSON
|
113
|
+
# blob as from the JSS, the Hash parsed from it will be stored here.
|
114
|
+
attr_reader :parsed_json
|
115
|
+
|
116
|
+
# Args are a hash (or group of named params)
|
117
|
+
# with these possible keys:
|
118
|
+
# raw_json: [String] A raw JSON blob for a full event as sent by the JSS
|
119
|
+
# If this is present, all other keys are ignored and the instance is
|
120
|
+
# built with this data.
|
121
|
+
# parsed_json: [Hash] A pre-parsed JSON blob for a full event.
|
122
|
+
# If this is present, all other keys are ignored and the instance is
|
123
|
+
# built with this data (however raw_json wins if both are provided)
|
124
|
+
# webhook_event: [String] The name of the event, one of the keys of EVENTS
|
125
|
+
# webhook_id: [Integer] The id of the webhook defined in the JSS
|
126
|
+
# webhook_name: [String] The name of the webhook defined in the JSS
|
127
|
+
# The remaning keys are the attributes of the Subject subclass for this
|
128
|
+
# event. Any not provided will be nil.
|
129
|
+
#
|
130
|
+
def initialize(**args)
|
131
|
+
if args[:raw_json]
|
132
|
+
@raw_json = args[:raw_json]
|
133
|
+
@parsed_json = JSON.parse @raw_json, symbolize_names: true
|
134
|
+
elsif args[:parsed_json]
|
135
|
+
@parsed_json = args[:parsed_json]
|
136
|
+
end
|
137
|
+
|
138
|
+
if @parsed_json
|
139
|
+
@webhook_name = @parsed_json[:webhook][:name]
|
140
|
+
@webhook_id = @parsed_json[:webhook][:id]
|
141
|
+
subject_data = @parsed_json[:event]
|
142
|
+
else
|
143
|
+
@webhook_name = args.delete :webhook_name
|
144
|
+
@webhook_id = args.delete :webhook_id
|
145
|
+
subject_data = args
|
146
|
+
end
|
147
|
+
|
148
|
+
@subject = self.class::SUBJECT_CLASS.new subject_data
|
149
|
+
end
|
150
|
+
|
151
|
+
end # class Event
|
152
|
+
|
153
|
+
end # module
|