banacle 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/example/Gemfile +8 -0
- data/example/Gemfile.lock +53 -0
- data/example/config.ru +62 -0
- data/lib/banacle/authenticator.rb +1 -11
- data/lib/banacle/handler.rb +16 -11
- data/lib/banacle/interactive_message/handler.rb +6 -2
- data/lib/banacle/interactive_message/renderer.rb +26 -38
- data/lib/banacle/slash_command/handler.rb +8 -4
- data/lib/banacle/slash_command/renderer.rb +21 -10
- data/lib/banacle/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac8dd15ec8a0ac5c80b7063b7aa35eb3234112814a895cd7978d74aca0b02523
|
4
|
+
data.tar.gz: 60225cc4f11757f0c5dc69cb2560bfbf6489c9c9ecb5b66a89a04ba9fcbe3dd2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50e850965e6310789a4afb79631c16a89b29d1eba9bf20332317354f468a5ce86431047ad6804d19d85253208bb781744e49f00630b27c2a74b812e10fd10ebe
|
7
|
+
data.tar.gz: 3abe80594a93b4a4a1d9bdeadd28d82516d6df16f62e2bdaab10e30b320538ef137e05a56e51292fe90d1eb5878da46dc3908353fbc7fce0ef49f7de0d3c3dc7
|
data/Gemfile.lock
CHANGED
data/example/Gemfile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
banacle (0.1.2)
|
5
|
+
aws-sdk-ec2
|
6
|
+
sinatra
|
7
|
+
unicorn
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
aws-eventstream (1.0.1)
|
13
|
+
aws-partitions (1.127.0)
|
14
|
+
aws-sdk-core (3.44.1)
|
15
|
+
aws-eventstream (~> 1.0)
|
16
|
+
aws-partitions (~> 1.0)
|
17
|
+
aws-sigv4 (~> 1.0)
|
18
|
+
jmespath (~> 1.0)
|
19
|
+
aws-sdk-ec2 (1.65.0)
|
20
|
+
aws-sdk-core (~> 3, >= 3.39.0)
|
21
|
+
aws-sigv4 (~> 1.0)
|
22
|
+
aws-sigv4 (1.0.3)
|
23
|
+
coderay (1.1.2)
|
24
|
+
jmespath (1.4.0)
|
25
|
+
kgio (2.11.2)
|
26
|
+
method_source (0.9.2)
|
27
|
+
mustermann (1.0.3)
|
28
|
+
pry (0.12.2)
|
29
|
+
coderay (~> 1.1.0)
|
30
|
+
method_source (~> 0.9.0)
|
31
|
+
rack (2.0.6)
|
32
|
+
rack-protection (2.0.5)
|
33
|
+
rack
|
34
|
+
raindrops (0.19.0)
|
35
|
+
sinatra (2.0.5)
|
36
|
+
mustermann (~> 1.0)
|
37
|
+
rack (~> 2.0)
|
38
|
+
rack-protection (= 2.0.5)
|
39
|
+
tilt (~> 2.0)
|
40
|
+
tilt (2.0.9)
|
41
|
+
unicorn (5.4.1)
|
42
|
+
kgio (~> 2.6)
|
43
|
+
raindrops (~> 0.7)
|
44
|
+
|
45
|
+
PLATFORMS
|
46
|
+
ruby
|
47
|
+
|
48
|
+
DEPENDENCIES
|
49
|
+
banacle!
|
50
|
+
pry
|
51
|
+
|
52
|
+
BUNDLED WITH
|
53
|
+
1.16.2
|
data/example/config.ru
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'banacle/authenticator'
|
3
|
+
require 'banacle/slash_command/handler'
|
4
|
+
require 'banacle/interactive_message/handler'
|
5
|
+
|
6
|
+
class App < Sinatra::Base
|
7
|
+
include Banacle
|
8
|
+
|
9
|
+
helpers do
|
10
|
+
def command_handler
|
11
|
+
@command_handler ||= SlashCommand::Handler.new.tap do |h|
|
12
|
+
h.set_authenticator!(CommandAuthenticator.new)
|
13
|
+
h
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def message_handler
|
18
|
+
@message_handler ||= InteractiveMessage::Handler.new.tap do |h|
|
19
|
+
h.set_authenticator!(MessageAuthenticator.new)
|
20
|
+
h
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
post '/slack/command' do
|
26
|
+
content_type :json
|
27
|
+
command_handler.handle(request)
|
28
|
+
end
|
29
|
+
|
30
|
+
post '/slack/message' do
|
31
|
+
content_type :json
|
32
|
+
message_handler.handle(request)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class CommandAuthenticator < Banacle::Authenticator
|
37
|
+
def authenticate(request)
|
38
|
+
params = request.params
|
39
|
+
|
40
|
+
team_id = params["team_id"]
|
41
|
+
# user_id = params["user_id"]
|
42
|
+
|
43
|
+
if team_id != "T0XXXXXXX"
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class MessageAuthenticator < Banacle::Authenticator
|
52
|
+
attr_reader :request
|
53
|
+
def authenticate(request)
|
54
|
+
payload = JSON.parse(request.params["payload"])
|
55
|
+
# team_id = payload["team"]["id"]
|
56
|
+
# user_id = payload["user"]["id"]
|
57
|
+
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
run App
|
@@ -1,17 +1,7 @@
|
|
1
1
|
module Banacle
|
2
2
|
class Authenticator
|
3
|
-
def self.authenticate(request)
|
4
|
-
new(request).authenticate
|
5
|
-
end
|
6
|
-
|
7
|
-
def initialize(request)
|
8
|
-
@request = request
|
9
|
-
end
|
10
|
-
|
11
|
-
attr_reader :request
|
12
|
-
|
13
3
|
# override
|
14
|
-
def authenticate
|
4
|
+
def authenticate(request)
|
15
5
|
end
|
16
6
|
end
|
17
7
|
end
|
data/lib/banacle/handler.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'banacle/authenticator'
|
1
2
|
require 'banacle/slack_validator'
|
2
3
|
|
3
4
|
module Banacle
|
@@ -13,10 +14,6 @@ module Banacle
|
|
13
14
|
return [401, {}, "invalid request"]
|
14
15
|
end
|
15
16
|
|
16
|
-
if auth && !auth.authenticate(request)
|
17
|
-
return [402, {}, "unauthenticated"]
|
18
|
-
end
|
19
|
-
|
20
17
|
handle_request
|
21
18
|
end
|
22
19
|
|
@@ -24,18 +21,26 @@ module Banacle
|
|
24
21
|
def handle_request
|
25
22
|
end
|
26
23
|
|
27
|
-
|
24
|
+
def set_authenticator!(auth)
|
25
|
+
unless auth.is_a?(Banacle::Authenticator)
|
26
|
+
raise InvalidAuthenticatorError.new(auth.inspect)
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
request.params["skip_validation"] || ENV["BANACLE_SKIP_VALIDATION"]
|
29
|
+
@auth = auth
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
private
|
33
|
+
|
34
|
+
def authenticated?
|
35
|
+
if auth && !auth.authenticate(request)
|
36
|
+
return false
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def skip_validation?
|
43
|
+
request.params["skip_validation"] || ENV["BANACLE_SKIP_VALIDATION"]
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|
@@ -6,8 +6,12 @@ module Banacle
|
|
6
6
|
module InteractiveMessage
|
7
7
|
class Handler < Banacle::Handler
|
8
8
|
def handle_request
|
9
|
-
|
10
|
-
|
9
|
+
unless authenticated?
|
10
|
+
return Renderer.render_unauthenticated
|
11
|
+
end
|
12
|
+
|
13
|
+
command = Parser.parse(JSON.parse(request_payload))
|
14
|
+
Renderer.render(request.params, command)
|
11
15
|
end
|
12
16
|
|
13
17
|
private
|
@@ -8,6 +8,18 @@ module Banacle
|
|
8
8
|
new(params, command).render
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.render_unauthenticated
|
12
|
+
self.render_error("you are not authorized to perform this action")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.render_error(error)
|
16
|
+
Slack::Response.new(
|
17
|
+
response_type: "ephemeral",
|
18
|
+
replace_original: false,
|
19
|
+
text: "An error occurred: #{error}",
|
20
|
+
).to_json
|
21
|
+
end
|
22
|
+
|
11
23
|
def initialize(params, command)
|
12
24
|
@params = params
|
13
25
|
@command = command
|
@@ -16,7 +28,6 @@ module Banacle
|
|
16
28
|
attr_reader :params, :command
|
17
29
|
|
18
30
|
def render
|
19
|
-
payload = JSON.parse(params["payload"], symbolize_names: true)
|
20
31
|
action = Slack::Action.new(payload[:actions].first)
|
21
32
|
|
22
33
|
if action.approved?
|
@@ -30,54 +41,39 @@ module Banacle
|
|
30
41
|
end
|
31
42
|
end
|
32
43
|
|
33
|
-
protected
|
34
|
-
|
35
|
-
# override
|
36
|
-
def authenticated_user?
|
37
|
-
true
|
38
|
-
end
|
39
|
-
|
40
44
|
private
|
41
45
|
|
42
46
|
def render_approved_message(payload, command)
|
43
47
|
unless valid_approver?
|
44
|
-
return render_error("you cannot approve the request by yourself")
|
48
|
+
return self.render_error("you cannot approve the request by yourself")
|
45
49
|
end
|
46
50
|
|
47
|
-
|
48
|
-
result = command.execute
|
51
|
+
result = command.execute
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
text = original_message_text
|
54
|
+
text += ":white_check_mark: *<@#{actioner_id}> approved this request*\n"
|
55
|
+
text += "Result:\n"
|
56
|
+
text += "```\n"
|
57
|
+
text += result
|
58
|
+
text += "```"
|
56
59
|
|
57
|
-
|
58
|
-
else
|
59
|
-
render_error("you are not permitted to approve the request")
|
60
|
-
end
|
60
|
+
render_replacing_message(text)
|
61
61
|
end
|
62
62
|
|
63
63
|
def render_rejected_message(payload, command)
|
64
64
|
unless valid_rejector?
|
65
|
-
return render_error("you cannot reject the request by yourself")
|
65
|
+
return self.render_error("you cannot reject the request by yourself")
|
66
66
|
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
text += ":no_entry_sign: *<@#{actioner_id}> rejected this request*"
|
68
|
+
text = original_message_text
|
69
|
+
text += ":no_entry_sign: *<@#{actioner_id}> rejected this request*"
|
71
70
|
|
72
|
-
|
73
|
-
else
|
74
|
-
render_error("you are not permitted to reject the request")
|
75
|
-
end
|
71
|
+
render_replacing_message(text)
|
76
72
|
end
|
77
73
|
|
78
74
|
def render_cancelled_message(payload, command)
|
79
75
|
unless valid_canceller?
|
80
|
-
return render_error("you cannot cancel the request by other than the requester")
|
76
|
+
return self.render_error("you cannot cancel the request by other than the requester")
|
81
77
|
end
|
82
78
|
|
83
79
|
text = original_message_text
|
@@ -94,14 +90,6 @@ module Banacle
|
|
94
90
|
).to_json
|
95
91
|
end
|
96
92
|
|
97
|
-
def render_error(error)
|
98
|
-
Slack::Response.new(
|
99
|
-
response_type: "ephemeral",
|
100
|
-
replace_original: false,
|
101
|
-
text: "An error occurred: #{error}",
|
102
|
-
).to_json
|
103
|
-
end
|
104
|
-
|
105
93
|
def valid_approver?
|
106
94
|
ENV['BANACLE_SKIP_VALIDATION'] || !self_actioned?
|
107
95
|
end
|
@@ -7,13 +7,17 @@ module Banacle
|
|
7
7
|
module SlashCommand
|
8
8
|
class Handler < Banacle::Handler
|
9
9
|
def handle_request
|
10
|
+
unless authenticated?
|
11
|
+
return Renderer.render_unauthenticated
|
12
|
+
end
|
13
|
+
|
10
14
|
begin
|
11
|
-
command =
|
12
|
-
rescue
|
13
|
-
return
|
15
|
+
command = Parser.parse(request_text)
|
16
|
+
rescue Error => e
|
17
|
+
return Renderer.render_error(e)
|
14
18
|
end
|
15
19
|
|
16
|
-
|
20
|
+
Renderer.render(request.params, command)
|
17
21
|
end
|
18
22
|
|
19
23
|
private
|
@@ -6,27 +6,34 @@ module Banacle
|
|
6
6
|
module SlashCommand
|
7
7
|
class Renderer
|
8
8
|
def self.render(params, command)
|
9
|
-
new
|
9
|
+
new(params, command).render
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
def render(params, command)
|
17
|
-
render_approval_request(params, command)
|
12
|
+
def self.render_unauthenticated
|
13
|
+
render_error("you are not authorized to perform this command")
|
18
14
|
end
|
19
15
|
|
20
|
-
def render_error(error)
|
16
|
+
def self.render_error(error)
|
21
17
|
Slack::Response.new(
|
22
18
|
response_type: "ephemeral",
|
23
19
|
text: "An error occurred: #{error}",
|
24
20
|
).to_json
|
25
21
|
end
|
26
22
|
|
27
|
-
def
|
23
|
+
def initialize(params, command)
|
24
|
+
@params = params
|
25
|
+
@command = command
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :params, :command
|
29
|
+
|
30
|
+
def render
|
31
|
+
render_approval_request
|
32
|
+
end
|
33
|
+
|
34
|
+
def render_approval_request
|
28
35
|
text = <<-EOS
|
29
|
-
<@#{
|
36
|
+
<@#{user_id}> wants to *#{command.action} NACL DENY entry* under the following conditions:
|
30
37
|
```
|
31
38
|
#{JSON.pretty_generate(command.to_h)}
|
32
39
|
```
|
@@ -51,6 +58,10 @@ module Banacle
|
|
51
58
|
],
|
52
59
|
).to_json
|
53
60
|
end
|
61
|
+
|
62
|
+
def user_id
|
63
|
+
params["user_id"]
|
64
|
+
end
|
54
65
|
end
|
55
66
|
end
|
56
67
|
end
|
data/lib/banacle/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: banacle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takuya Kosugiyama
|
@@ -145,6 +145,9 @@ files:
|
|
145
145
|
- docs/demo1.png
|
146
146
|
- docs/demo2.png
|
147
147
|
- docs/nacl.png
|
148
|
+
- example/Gemfile
|
149
|
+
- example/Gemfile.lock
|
150
|
+
- example/config.ru
|
148
151
|
- lib/banacle.rb
|
149
152
|
- lib/banacle/app.rb
|
150
153
|
- lib/banacle/authenticator.rb
|