chook 1.0.1.b1 → 1.1.5b1
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 +5 -5
- data/CHANGES.md +56 -0
- data/README.md +397 -145
- data/bin/chook-server +31 -1
- data/data/chook.conf.example +183 -0
- data/data/com.pixar.chook-server.plist +20 -0
- data/data/sample_handlers/RestAPIOperation.rb +11 -11
- data/data/sample_handlers/SmartGroupComputerMembershipChange.rb +3 -6
- data/data/sample_jsons/SmartGroupComputerMembershipChange.json +3 -1
- data/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +3 -1
- data/lib/chook/configuration.rb +27 -8
- data/lib/chook/event.rb +6 -1
- data/lib/chook/event/handled_event.rb +36 -9
- data/lib/chook/event/handled_event/handlers.rb +252 -99
- data/lib/chook/event/handled_event_logger.rb +86 -0
- data/lib/chook/event_handling.rb +1 -0
- data/lib/chook/foundation.rb +3 -0
- data/lib/chook/procs.rb +17 -1
- data/lib/chook/server.rb +73 -72
- data/lib/chook/server/auth.rb +164 -0
- data/lib/chook/server/log.rb +215 -0
- data/lib/chook/server/public/css/chook.css +133 -0
- data/lib/chook/server/public/imgs/ChookLogoAlMcWhiggin.png +0 -0
- data/lib/chook/server/public/js/chook.js +126 -0
- data/lib/chook/server/public/js/logstream.js +101 -0
- data/lib/chook/server/routes.rb +28 -0
- data/lib/chook/server/routes/handle_by_name.rb +65 -0
- data/lib/chook/server/routes/handle_webhook_event.rb +27 -3
- data/lib/chook/server/routes/handlers.rb +52 -0
- data/lib/chook/server/routes/home.rb +48 -1
- data/lib/chook/server/routes/log.rb +105 -0
- data/lib/chook/server/routes/login_logout.rb +48 -0
- data/lib/chook/server/views/admin.haml +11 -0
- data/lib/chook/server/views/bak.haml +48 -0
- data/lib/chook/server/views/config.haml +15 -0
- data/lib/chook/server/views/handlers.haml +63 -0
- data/lib/chook/server/views/layout.haml +64 -0
- data/lib/chook/server/views/logstream.haml +33 -0
- data/lib/chook/server/views/sketch_admin +44 -0
- data/lib/chook/subject.rb +13 -2
- data/lib/chook/subject/dep_device.rb +81 -0
- data/lib/chook/subject/policy_finished.rb +43 -0
- data/lib/chook/subject/smart_group.rb +6 -0
- data/lib/chook/subject/test_subject.rb +2 -2
- data/lib/chook/version.rb +1 -1
- metadata +78 -17
@@ -29,9 +29,33 @@ module Chook
|
|
29
29
|
class Server < Sinatra::Base
|
30
30
|
|
31
31
|
post '/handle_webhook_event' do
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
# enforce http basic auth if needed
|
33
|
+
protect_via_basic_auth!
|
34
|
+
|
35
|
+
# rewind to ensure read-pointer is at the start
|
36
|
+
request.body.rewind #
|
37
|
+
raw_json = request.body.read
|
38
|
+
|
39
|
+
event = Chook::HandledEvent.parse_event raw_json
|
40
|
+
if event.nil?
|
41
|
+
logger.error "Empty JSON from #{request.ip}"
|
42
|
+
result = 400
|
43
|
+
else
|
44
|
+
|
45
|
+
event.logger.debug "START From #{request.ip}, WebHook '#{event.webhook_name}' (id: #{event.webhook_id})"
|
46
|
+
event.logger.debug "Thread id: #{Thread.current.object_id}; JSON: #{raw_json}"
|
47
|
+
|
48
|
+
result = event.handle
|
49
|
+
|
50
|
+
event.logger.debug "END #{result}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# this route shouldn't have a session expiration
|
54
|
+
# And when it does, the date format is wrong, and the
|
55
|
+
# JAMFSoftwareServerLog complains about it for every
|
56
|
+
# webhook sent.
|
57
|
+
env['rack.session.options'].delete :expire_after
|
58
|
+
result
|
35
59
|
end # post
|
36
60
|
|
37
61
|
end # class
|
@@ -0,0 +1,52 @@
|
|
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
|
+
# see server.rb
|
29
|
+
class Server < Sinatra::Base
|
30
|
+
|
31
|
+
# reload the handlers
|
32
|
+
get '/reload_handlers' do
|
33
|
+
logger.info 'Reloading handlers'
|
34
|
+
Chook::HandledEvent::Handlers.load_handlers reload: true
|
35
|
+
'Handlers reloaded'
|
36
|
+
end # get /
|
37
|
+
|
38
|
+
# used by javascript to fetch the content of a handler file
|
39
|
+
get '/handler_code' do
|
40
|
+
file = Pathname.new params[:filepath]
|
41
|
+
|
42
|
+
# only if its a known handler path
|
43
|
+
if Chook::HandledEvent::Handlers.all_handler_paths.include?(file) && file.file?
|
44
|
+
body file.read
|
45
|
+
else
|
46
|
+
404
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end # class
|
51
|
+
|
52
|
+
end # module
|
@@ -29,7 +29,54 @@ module Chook
|
|
29
29
|
class Server < Sinatra::Base
|
30
30
|
|
31
31
|
get '/' do
|
32
|
-
|
32
|
+
|
33
|
+
# a list of current handlers for the admin page
|
34
|
+
@handlers_for_admin_page = []
|
35
|
+
|
36
|
+
Chook::HandledEvent::Handlers.handlers.keys.sort.each do |eventname|
|
37
|
+
Chook::HandledEvent::Handlers.handlers[eventname].each do |handler|
|
38
|
+
if handler.is_a? Pathname
|
39
|
+
file = handler
|
40
|
+
type = :external
|
41
|
+
else
|
42
|
+
file = handler.handler_file
|
43
|
+
type = :internal
|
44
|
+
end # if else
|
45
|
+
@handlers_for_admin_page << { event: eventname, file: file, type: type }
|
46
|
+
end # handlers each
|
47
|
+
end # Handlers.handlers.each
|
48
|
+
|
49
|
+
# a list of current named handlers for the admin page
|
50
|
+
@named_handlers_for_admin_page = []
|
51
|
+
|
52
|
+
Chook::HandledEvent::Handlers.named_handlers.each do |name, handler|
|
53
|
+
if handler.is_a? Pathname
|
54
|
+
file = handler
|
55
|
+
type = :external
|
56
|
+
else
|
57
|
+
file = handler.handler_file
|
58
|
+
type = :internal
|
59
|
+
end # if else
|
60
|
+
@named_handlers_for_admin_page << { file: file, type: type }
|
61
|
+
end # handlers each
|
62
|
+
|
63
|
+
|
64
|
+
# the current config, for the admin page
|
65
|
+
@config_text =
|
66
|
+
if Chook::Configuration::DEFAULT_CONF_FILE.file?
|
67
|
+
@config_src = Chook::Configuration::DEFAULT_CONF_FILE.to_s
|
68
|
+
Chook::Configuration::DEFAULT_CONF_FILE.read
|
69
|
+
|
70
|
+
elsif Chook::Configuration::SAMPLE_CONF_FILE.file?
|
71
|
+
@config_src = "Using default values, showing sample config file at #{Chook::Configuration::SAMPLE_CONF_FILE}"
|
72
|
+
Chook::Configuration::SAMPLE_CONF_FILE.read
|
73
|
+
|
74
|
+
else
|
75
|
+
@config_src = "No #{Chook::Configuration::DEFAULT_CONF_FILE} or sample config file found."
|
76
|
+
@config_src
|
77
|
+
end
|
78
|
+
|
79
|
+
haml :admin
|
33
80
|
end # get /
|
34
81
|
|
35
82
|
end # class
|
@@ -0,0 +1,105 @@
|
|
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
|
+
# see server.rb
|
29
|
+
class Server < Sinatra::Base
|
30
|
+
|
31
|
+
# External Handlers can use this route to make log entries.
|
32
|
+
#
|
33
|
+
# The request body must be a JSON object (Hash) wth 2 keys 'level' and 'message'
|
34
|
+
# where both values are strings
|
35
|
+
#
|
36
|
+
# Here's an example with curl, split to multi-line for clarity:
|
37
|
+
#
|
38
|
+
# curl -H "Content-Type: application/json" \
|
39
|
+
# -X POST \
|
40
|
+
# --data '{"level":"debug", "message":"It Worked"}' \
|
41
|
+
# https://user:passwd@chookserver.myorg.org:443/log
|
42
|
+
#
|
43
|
+
post '/log' do
|
44
|
+
protect_via_basic_auth!
|
45
|
+
|
46
|
+
request.body.rewind # in case someone already read it
|
47
|
+
raw = request.body.read
|
48
|
+
|
49
|
+
begin
|
50
|
+
logentry = JSON.parse raw, symbolize_names: true
|
51
|
+
raise if logentry[:level].to_s.empty? || logentry[:message].to_s.empty?
|
52
|
+
rescue
|
53
|
+
Chook::Server::Log.logger.error "Malformed log entry JSON from #{request.ip}: #{raw}"
|
54
|
+
halt 409, "Malformed log entry JSON: #{raw}"
|
55
|
+
end
|
56
|
+
|
57
|
+
level = logentry[:level].to_sym
|
58
|
+
level = :unknown unless Chook::Server::Log::LOG_LEVELS.key? level
|
59
|
+
Chook::Server::Log.logger.send level, "ExternalEntry: #{logentry[:message]}"
|
60
|
+
|
61
|
+
{ result: 'logged', level: level }.to_json
|
62
|
+
end # post /
|
63
|
+
|
64
|
+
# AJAXy access to a log stream
|
65
|
+
# When an admin displays the log on the chook admin/home page,
|
66
|
+
# the page's javascript starts the stream as an EventSource
|
67
|
+
# from this url.
|
68
|
+
#
|
69
|
+
# The innards are taken almost verbatim from the Sinatra README
|
70
|
+
# docs.
|
71
|
+
#
|
72
|
+
# See also logstream.js and views/admin.haml
|
73
|
+
#
|
74
|
+
#
|
75
|
+
get '/subscribe_to_log_stream', provides: 'text/event-stream' do
|
76
|
+
content_type 'text/event-stream'
|
77
|
+
cache_control 'no-cache'
|
78
|
+
|
79
|
+
# register a client's interest in server events
|
80
|
+
stream(:keep_open) do |outbound_stream|
|
81
|
+
# add this connection to the array of streams
|
82
|
+
Chook::Server::Log.log_streams[outbound_stream] = request.ip
|
83
|
+
logger.debug "Added log stream for #{request.ip}"
|
84
|
+
# purge dead connections
|
85
|
+
Chook::Server::Log.clean_log_streams
|
86
|
+
end # stream
|
87
|
+
end
|
88
|
+
|
89
|
+
# set the log level via the admin page.
|
90
|
+
put '/set_log_level/:level' do
|
91
|
+
level = params[:level].to_sym
|
92
|
+
level = :unknown unless Chook::Server::Log::LOG_LEVELS.key? level
|
93
|
+
Chook.logger.level = level
|
94
|
+
Chook.logger.unknown "Log level changed, now: #{level}"
|
95
|
+
{ result: 'level changed', level: level }.to_json
|
96
|
+
end
|
97
|
+
|
98
|
+
# get the log level via the admin page.
|
99
|
+
get '/current_log_level' do
|
100
|
+
Chook::Server::Log::LOG_LEVELS.invert[Chook.logger.level].to_s
|
101
|
+
end
|
102
|
+
|
103
|
+
end # class
|
104
|
+
|
105
|
+
end # module
|
@@ -0,0 +1,48 @@
|
|
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
|
+
# see server.rb
|
29
|
+
class Server < Sinatra::Base
|
30
|
+
|
31
|
+
# reload the handlers
|
32
|
+
get '/logout' do
|
33
|
+
session[:authed_admin] = nil
|
34
|
+
session[:auth_failed] = nil
|
35
|
+
redirect '/'
|
36
|
+
end # get /
|
37
|
+
|
38
|
+
# reload the handlers
|
39
|
+
post '/login' do
|
40
|
+
Chook.logger.debug "Attempting to log in #{params[:username]}"
|
41
|
+
session[:auth_failed] = !authenticate_admin(params[:username], params[:password])
|
42
|
+
redirect '/'
|
43
|
+
end # get /
|
44
|
+
|
45
|
+
|
46
|
+
end # class
|
47
|
+
|
48
|
+
end # module
|
@@ -0,0 +1,48 @@
|
|
1
|
+
%hr/
|
2
|
+
.section_label#log_label
|
3
|
+
The Live Chook Log
|
4
|
+
|
5
|
+
%button#view_log_btn{ type: 'button', onClick: 'view_log();', title: 'view the live Chook log' }
|
6
|
+
View
|
7
|
+
%button#hide_log_btn{ type: 'button', onClick: 'hide_log();', title: 'hide the live Chook log' }
|
8
|
+
Hide
|
9
|
+
Log Level:
|
10
|
+
%select#log_level_select{ onchange: 'change_log_level();' }
|
11
|
+
%option{ value: 'fatal', selected: Chook.logger.level == Logger::FATAL } fatal
|
12
|
+
%option{ value: 'error', selected: Chook.logger.level == Logger::ERROR } error
|
13
|
+
%option{ value: 'warn', selected: Chook.logger.level == Logger::WARN } warn
|
14
|
+
%option{ value: 'info', selected: Chook.logger.level == Logger::INFO } info
|
15
|
+
%option{ value: 'debug', selected: Chook.logger.level == Logger::DEBUG } debug
|
16
|
+
|
17
|
+
#logbox_div
|
18
|
+
#logbox_btns
|
19
|
+
%input#pause_log{ type: 'checkbox', checked: false, onclick: 'update_logbox();' }
|
20
|
+
Pause
|
21
|
+
|
22
|
+
%button#clear_log_btn{ type: 'button', onClick: 'clear_log();', title: 'clear the live Chook log' }
|
23
|
+
Clear
|
24
|
+
|
25
|
+
// Log Level: [popup list] (set)
|
26
|
+
%textarea.monospaced#logbox{ readonly: true, rows: 20, cols: 150 }
|
27
|
+
|
28
|
+
%hr/
|
29
|
+
.section_label#handlers_label
|
30
|
+
Current Webhook Handlers (#{@handlers_for_admin_page.size})
|
31
|
+
|
32
|
+
|
33
|
+
%button#view_handlers_btn{ type: 'button', onClick: 'view_handlers();', title: 'view the handler list' }
|
34
|
+
View
|
35
|
+
%button#hide_handlers_btn{ type: 'button', onClick: 'hide_handlers();', title: 'hide the handler list' }
|
36
|
+
Hide
|
37
|
+
|
38
|
+
|
39
|
+
Handler Directory:
|
40
|
+
%span.monospaced
|
41
|
+
= Chook.config.handler_dir.to_s
|
42
|
+
|
43
|
+
#handlers_div
|
44
|
+
%table#handlers_table
|
45
|
+
%tr
|
46
|
+
%th Event
|
47
|
+
%th Handler Type
|
48
|
+
%th File Name
|
@@ -0,0 +1,15 @@
|
|
1
|
+
.section_label#config_label
|
2
|
+
%button#view_config_btn{ type: 'button', onClick: 'view_config();', title: 'view the config file' }
|
3
|
+
View
|
4
|
+
%button#hide_config_btn{ type: 'button', onClick: 'hide_config();', title: 'hide the config file' }
|
5
|
+
Hide
|
6
|
+
|
7
|
+
|
8
|
+
Configuration
|
9
|
+
|
10
|
+
#config_div
|
11
|
+
Config file:
|
12
|
+
%span.monospaced= @config_src
|
13
|
+
|
14
|
+
#config_viewer_div
|
15
|
+
%textarea.monospaced#config_box{ readonly: true, rows: 20, cols: 150 }= @config_text
|
@@ -0,0 +1,63 @@
|
|
1
|
+
.section_label#handlers_label
|
2
|
+
%button#view_handlers_btn{ type: 'button', onClick: 'view_handlers();', title: 'view the handler list' }
|
3
|
+
View
|
4
|
+
%button#hide_handlers_btn{ type: 'button', onClick: 'hide_handlers();', title: 'hide the handler list' }
|
5
|
+
Hide
|
6
|
+
|
7
|
+
|
8
|
+
Current Webhook Handlers (#{@handlers_for_admin_page.size + @named_handlers_for_admin_page.size})
|
9
|
+
|
10
|
+
%button#reload_all_handlers_btn{ type: 'button', onClick: 'reload_handlers();', title: 'reload all handlers' }
|
11
|
+
Reload All
|
12
|
+
|
13
|
+
%span#reloaded_notification
|
14
|
+
|
15
|
+
#handlers_div
|
16
|
+
General Handler Directory:
|
17
|
+
%span.monospaced= Chook.config.handler_dir.to_s
|
18
|
+
|
19
|
+
|
20
|
+
%table#handlers_table
|
21
|
+
%tr#handlers_table_header_row
|
22
|
+
%th.handlers_table_cell File Name
|
23
|
+
%th.handlers_table_cell{ width: '10%' } Handler Type
|
24
|
+
%th.handlers_table_cell Actions
|
25
|
+
|
26
|
+
- @handlers_for_admin_page.each do |hndlr_info|
|
27
|
+
%tr
|
28
|
+
%td.handlers_table_cell= hndlr_info[:file].basename.to_s
|
29
|
+
%td.handlers_table_cell= hndlr_info[:type].to_s
|
30
|
+
%td.handlers_table_cell
|
31
|
+
%button.edit_handler_btn{ type: 'button', onClick: "view_handler_code('#{hndlr_info[:file]}', '#{hndlr_info[:type]}');", title: 'View this handler' }
|
32
|
+
View
|
33
|
+
%br
|
34
|
+
%br
|
35
|
+
Named Handler Directory:
|
36
|
+
%span.monospaced= Chook.config.handler_dir.to_s + "/#{Chook::HandledEvent::Handlers::NAMED_HANDLER_SUBDIR}"
|
37
|
+
|
38
|
+
|
39
|
+
%table#handlers_table
|
40
|
+
%tr#handlers_table_header_row
|
41
|
+
%th.handlers_table_cell File Name
|
42
|
+
%th.handlers_table_cell{ width: '10%' } Handler Type
|
43
|
+
%th.handlers_table_cell Actions
|
44
|
+
|
45
|
+
- @named_handlers_for_admin_page.each do |hndlr_info|
|
46
|
+
%tr
|
47
|
+
%td.handlers_table_cell= hndlr_info[:file].basename.to_s
|
48
|
+
%td.handlers_table_cell= hndlr_info[:type].to_s
|
49
|
+
%td.handlers_table_cell
|
50
|
+
%button.edit_handler_btn{ type: 'button', onClick: "view_handler_code('#{hndlr_info[:file]}', '#{hndlr_info[:type]}');", title: 'View this handler' }
|
51
|
+
View
|
52
|
+
|
53
|
+
#handler_viewer_div
|
54
|
+
%input#currently_viewing_handler_file{ name: 'currently_viewing_handler_file', type: :hidden }
|
55
|
+
%input#currently_editing_handler_type{ name: 'currently_editing_handler_type', type: :hidden }
|
56
|
+
#currently_viewing_handler_label
|
57
|
+
%button#hide_handler_viewer_btn{ type: 'button', onClick: 'hide_handler_viewer();', title: 'hide the handler editor' }
|
58
|
+
Hide
|
59
|
+
|
60
|
+
%span.monospaced#currently_viewing_filename -nothing-
|
61
|
+
|
62
|
+
|
63
|
+
%textarea.monospaced#handler_viewer{ rows: 35 , readonly: true }
|
@@ -0,0 +1,64 @@
|
|
1
|
+
!!!
|
2
|
+
%html{ lang: 'en' }
|
3
|
+
|
4
|
+
%head
|
5
|
+
|
6
|
+
%meta{ charset: 'UTF-8' }
|
7
|
+
%title
|
8
|
+
Chook
|
9
|
+
|
10
|
+
/ CSS
|
11
|
+
%link{ href: '/css/chook.css', rel: 'stylesheet' }
|
12
|
+
|
13
|
+
/ JavaScript
|
14
|
+
%script{ type: 'text/javascript', language: 'javascript', src: '/js/chook.js' }
|
15
|
+
%script{ type: 'text/javascript', language: 'javascript', src: '/js/logstream.js' }
|
16
|
+
|
17
|
+
%body
|
18
|
+
/ Top
|
19
|
+
#pageheader
|
20
|
+
%table{ width: '100%' }
|
21
|
+
%tr
|
22
|
+
%td{ valign: 'bottom', width: '120' }
|
23
|
+
#header_logo
|
24
|
+
%img{ alt: '', height: '120', src: '/imgs/ChookLogoAlMcWhiggin.png', width: '120' }
|
25
|
+
#header_version
|
26
|
+
v#{Chook::VERSION}
|
27
|
+
%td
|
28
|
+
#definition
|
29
|
+
%span.chook_title Chook
|
30
|
+
%br/
|
31
|
+
%span.def_pronunciation /tʃʊk/ (also chookie /ˈtʃʊki/ )
|
32
|
+
%br/
|
33
|
+
%span.def_part_of_speech noun
|
34
|
+
%span.def_dialect Australian/NZ informal
|
35
|
+
%br/
|
36
|
+
%span.def_definition a chicken or fowl
|
37
|
+
%td#serverstats{ valign: 'bottom' }
|
38
|
+
Server started: #{Chook::Server.starttime.strftime '%Y-%m-%d %H:%M:%S'}
|
39
|
+
%br/
|
40
|
+
(#{Chook::Server.uptime})
|
41
|
+
|
42
|
+
%hr/
|
43
|
+
- if Chook.config.admin_user
|
44
|
+
#login_logout_div
|
45
|
+
|
46
|
+
- if session[:authed_admin]
|
47
|
+
%a{ href: '/logout' }
|
48
|
+
%button#logout_btn{ type: 'button' } Log Out
|
49
|
+
= yield
|
50
|
+
|
51
|
+
- else
|
52
|
+
%form#login_form{ name: 'login_form', method: 'POST', action: '/login' }
|
53
|
+
- if Chook.config.admin_user == Chook::Server::Auth::USE_JAMF_ADMIN_USER
|
54
|
+
Jamf Pro
|
55
|
+
Username:
|
56
|
+
%input#username{ type: :text, name: 'username' }
|
57
|
+
Password:
|
58
|
+
%input#password{ type: :password, name: 'password' }
|
59
|
+
%input#login_btn{ type: :submit, value: 'Log In' }
|
60
|
+
- if session[:auth_failed]
|
61
|
+
%span#login_incorrect Login Incorrect!
|
62
|
+
|
63
|
+
- else
|
64
|
+
= yield
|