banacle 0.2.0 → 0.2.1
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +5 -1
- data/config.ru +5 -1
- data/example/Gemfile.lock +1 -1
- data/example/README.md +6 -0
- data/example/config.ru +19 -55
- data/lib/banacle.rb +2 -1
- data/lib/banacle/app.rb +33 -5
- data/lib/banacle/aws_wrapper/nacl.rb +1 -1
- data/lib/banacle/config.rb +19 -0
- data/lib/banacle/interactive_message/authenticator.rb +30 -0
- data/lib/banacle/interactive_message/handler.rb +77 -9
- data/lib/banacle/interactive_message/renderer.rb +10 -73
- data/lib/banacle/interactive_message/request.rb +37 -0
- data/lib/banacle/slack_validator.rb +4 -6
- data/lib/banacle/slash_command/authenticator.rb +13 -0
- data/lib/banacle/slash_command/handler.rb +28 -9
- data/lib/banacle/slash_command/renderer.rb +6 -19
- data/lib/banacle/slash_command/request.rb +23 -0
- data/lib/banacle/version.rb +1 -1
- metadata +8 -4
- data/lib/banacle/authenticator.rb +0 -7
- data/lib/banacle/handler.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eefa4ead64f9bdf4ed0db630e7f916f57d59a4910de1f8170f7a5d9ebedde89f
|
4
|
+
data.tar.gz: e84912019edc3da37cd5d28d58e1371d12ae35fa9dd749e7d479b66c0d6e7506
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 148fee60c884547dbefd99baaef7866856fe93f4969100618c33fa6ee04093db0a96fd7403f70b154131db36b6766a3233ef38e78377ec39b8cfdcf5a882e933
|
7
|
+
data.tar.gz: 6da6d0fc243a28188f6b3d6fd1f7732d3b0c61c4ad48e9f0b8d46938809d25616e00db751bd92df3054f3681ea00f41b08a0d1d8b957b3c0bfda7d3c1399d7d3
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,11 @@ Banacle is supposed to be run as a Sinatra server. You can run it simply by `rac
|
|
27
27
|
- `/slack/command`: handle Slash Command
|
28
28
|
- `/slack/message`: handle Interactive Message
|
29
29
|
|
30
|
-
###
|
30
|
+
### Customize authentication
|
31
|
+
You can customize Banacle by using request handler modules.
|
32
|
+
See example directory which implements a customized authentication feature for details.
|
33
|
+
|
34
|
+
## Example: ban 1.2.3.4 from my VPC
|
31
35
|
|
32
36
|
Execute an command that create a DENY NACL entry for 1.2.3.4 on a VPC named "test" in ap-northeast-1.
|
33
37
|
|
data/config.ru
CHANGED
data/example/Gemfile.lock
CHANGED
data/example/README.md
ADDED
data/example/config.ru
CHANGED
@@ -1,62 +1,26 @@
|
|
1
|
-
require '
|
2
|
-
require 'banacle/authenticator'
|
1
|
+
require 'banacle'
|
3
2
|
require 'banacle/slash_command/handler'
|
4
3
|
require 'banacle/interactive_message/handler'
|
5
4
|
|
6
|
-
class
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
5
|
+
class CommandAuthenticator < Banacle::SlashCommand::Authenticator
|
6
|
+
def authenticate_requester!(request)
|
7
|
+
super
|
8
|
+
if request.user_id != "U0XXXXXXX"
|
9
|
+
raise NotAuthenticatedError.new("You are not authorized to perform this command")
|
45
10
|
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
11
|
end
|
60
12
|
end
|
61
13
|
|
62
|
-
|
14
|
+
config = Banacle::Config.new(
|
15
|
+
slack_signing_secret: ENV.fetch('BANACLE_SLACK_SIGNING_SECRET'),
|
16
|
+
slash_command: {
|
17
|
+
authenticator: CommandAuthenticator,
|
18
|
+
},
|
19
|
+
approval_request: {
|
20
|
+
attachment: {
|
21
|
+
text: "*Approval Request* (can be approved by only SRE members except the requester)",
|
22
|
+
},
|
23
|
+
},
|
24
|
+
)
|
25
|
+
|
26
|
+
run Banacle.app(config)
|
data/lib/banacle.rb
CHANGED
data/lib/banacle/app.rb
CHANGED
@@ -1,21 +1,49 @@
|
|
1
1
|
require 'sinatra/base'
|
2
|
-
require 'sinatra/reloader'
|
3
2
|
require 'banacle/slash_command/handler'
|
4
3
|
require 'banacle/interactive_message/handler'
|
5
4
|
|
6
5
|
module Banacle
|
6
|
+
def self.app(*args)
|
7
|
+
App.rack(*args)
|
8
|
+
end
|
9
|
+
|
7
10
|
class App < Sinatra::Base
|
8
|
-
|
9
|
-
|
11
|
+
CONTEXT_RACK_ENV_NAME = 'banacle.ctx'
|
12
|
+
|
13
|
+
def self.rack(config={})
|
14
|
+
klass = App
|
15
|
+
|
16
|
+
context = initialize_context(config)
|
17
|
+
lambda { |env|
|
18
|
+
env[CONTEXT_RACK_ENV_NAME] = context
|
19
|
+
klass.call(env)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.initialize_context(config)
|
24
|
+
{
|
25
|
+
config: config,
|
26
|
+
}
|
10
27
|
end
|
11
28
|
|
12
29
|
helpers do
|
30
|
+
def context
|
31
|
+
request.env[CONTEXT_RACK_ENV_NAME]
|
32
|
+
end
|
33
|
+
|
34
|
+
def config
|
35
|
+
context[:config]
|
36
|
+
end
|
37
|
+
|
13
38
|
def command_handler
|
14
|
-
@command_handler ||= SlashCommand::Handler.new
|
39
|
+
@command_handler ||= SlashCommand::Handler.new(config)
|
15
40
|
end
|
16
41
|
|
17
42
|
def message_handler
|
18
|
-
@message_handler ||= InteractiveMessage::Handler.new
|
43
|
+
@message_handler ||= InteractiveMessage::Handler.new(
|
44
|
+
config,
|
45
|
+
auth: InteractiveMessage::Authenticator.new,
|
46
|
+
)
|
19
47
|
end
|
20
48
|
end
|
21
49
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Banacle
|
2
|
+
module InteractiveMessage
|
3
|
+
class Authenticator
|
4
|
+
class Error < StandardError; end
|
5
|
+
class NotAuthenticatedError < Error; end
|
6
|
+
|
7
|
+
# override to implement your own validation
|
8
|
+
def authenticate_approver!(request)
|
9
|
+
if request.self_actioned?
|
10
|
+
raise NotAuthenticatedError.new("you cannot approve the request by yourself")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# override to implement your own validation
|
15
|
+
def authenticate_rejector!(request)
|
16
|
+
if request.self_actioned?
|
17
|
+
raise NotAuthenticatedError.new("you cannot reject the request by yourself")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# override to implement your own validation
|
22
|
+
def authenticate_canceller!(request)
|
23
|
+
unless request.self_actioned?
|
24
|
+
raise NotAuthenticatedError.new("you cannot cancel the request by other than the requester")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,23 +1,91 @@
|
|
1
|
-
require 'banacle/
|
1
|
+
require 'banacle/slack_validator'
|
2
|
+
require 'banacle/interactive_message/authenticator'
|
2
3
|
require 'banacle/interactive_message/parser'
|
3
4
|
require 'banacle/interactive_message/renderer'
|
5
|
+
require 'banacle/interactive_message/request'
|
4
6
|
|
5
7
|
module Banacle
|
6
8
|
module InteractiveMessage
|
7
|
-
class Handler
|
8
|
-
def
|
9
|
-
|
10
|
-
|
9
|
+
class Handler
|
10
|
+
def initialize(config, auth: nil)
|
11
|
+
@config = config
|
12
|
+
@auth = auth
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :config, :auth
|
16
|
+
attr_accessor :request
|
17
|
+
|
18
|
+
def handle(raw_request)
|
19
|
+
unless slack_validator.valid_signature?(raw_request)
|
20
|
+
return [401, {}, "invalid signagure"]
|
11
21
|
end
|
12
22
|
|
13
|
-
|
14
|
-
|
23
|
+
self.request = Request.new(raw_request)
|
24
|
+
|
25
|
+
if request.action.approved?
|
26
|
+
handle_approval
|
27
|
+
elsif request.action.rejected?
|
28
|
+
handle_reject
|
29
|
+
elsif request.action.cancelled?
|
30
|
+
handle_cancellation
|
31
|
+
end
|
15
32
|
end
|
16
33
|
|
17
34
|
private
|
18
35
|
|
19
|
-
def
|
20
|
-
|
36
|
+
def handle_approval
|
37
|
+
begin
|
38
|
+
authenticate_approver!
|
39
|
+
rescue Authenticator::Error => e
|
40
|
+
return Renderer.render_error(e)
|
41
|
+
end
|
42
|
+
|
43
|
+
result = Parser.parse(request.payload).execute
|
44
|
+
renderer.render_approved_message(result)
|
45
|
+
end
|
46
|
+
|
47
|
+
def handle_reject
|
48
|
+
begin
|
49
|
+
authenticate_rejector!
|
50
|
+
rescue Authenticator::Error => e
|
51
|
+
return Renderer.render_error(e)
|
52
|
+
end
|
53
|
+
|
54
|
+
renderer.render_rejected_message
|
55
|
+
end
|
56
|
+
|
57
|
+
def handle_cancellation
|
58
|
+
begin
|
59
|
+
authenticate_canceller!
|
60
|
+
rescue Authenticator::Error => e
|
61
|
+
return Renderer.render_error(e)
|
62
|
+
end
|
63
|
+
|
64
|
+
renderer.render_cancelled_message
|
65
|
+
end
|
66
|
+
|
67
|
+
def renderer
|
68
|
+
Renderer.new(request, config)
|
69
|
+
end
|
70
|
+
|
71
|
+
def slack_validator
|
72
|
+
@slack_validator ||= SlackValidator.new(config[:slack_signing_secret])
|
73
|
+
end
|
74
|
+
|
75
|
+
def authenticate_approver!
|
76
|
+
auth.authenticate_approver!(request)
|
77
|
+
end
|
78
|
+
|
79
|
+
def authenticate_rejector!
|
80
|
+
auth.authenticate_rejector!(request)
|
81
|
+
end
|
82
|
+
|
83
|
+
def authenticate_canceller!
|
84
|
+
auth.authenticate_canceller!(request)
|
85
|
+
end
|
86
|
+
|
87
|
+
def auth
|
88
|
+
(config.dig(:interactive_message, :authenticator) || Authenticator).new
|
21
89
|
end
|
22
90
|
end
|
23
91
|
end
|
@@ -1,17 +1,8 @@
|
|
1
1
|
require 'banacle/slack'
|
2
|
-
require 'banacle/slash_command/command'
|
3
2
|
|
4
3
|
module Banacle
|
5
4
|
module InteractiveMessage
|
6
5
|
class Renderer
|
7
|
-
def self.render(params, command)
|
8
|
-
new(params, command).render
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.render_unauthenticated
|
12
|
-
self.render_error("you are not authorized to perform this action")
|
13
|
-
end
|
14
|
-
|
15
6
|
def self.render_error(error)
|
16
7
|
Slack::Response.new(
|
17
8
|
response_type: "ephemeral",
|
@@ -20,36 +11,14 @@ module Banacle
|
|
20
11
|
).to_json
|
21
12
|
end
|
22
13
|
|
23
|
-
def initialize(
|
24
|
-
@
|
25
|
-
@
|
14
|
+
def initialize(request, config)
|
15
|
+
@request = request
|
16
|
+
@config = config
|
26
17
|
end
|
27
18
|
|
28
|
-
attr_reader :
|
29
|
-
|
30
|
-
def render
|
31
|
-
action = Slack::Action.new(payload[:actions].first)
|
32
|
-
|
33
|
-
if action.approved?
|
34
|
-
render_approved_message(payload, command)
|
35
|
-
elsif action.rejected?
|
36
|
-
render_rejected_message(payload, command)
|
37
|
-
elsif action.cancelled?
|
38
|
-
render_cancelled_message(payload, command)
|
39
|
-
else
|
40
|
-
# Do nothing
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def render_approved_message(payload, command)
|
47
|
-
unless valid_approver?
|
48
|
-
return self.render_error("you cannot approve the request by yourself")
|
49
|
-
end
|
50
|
-
|
51
|
-
result = command.execute
|
19
|
+
attr_reader :request, :config
|
52
20
|
|
21
|
+
def render_approved_message(result)
|
53
22
|
text = original_message_text
|
54
23
|
text += ":white_check_mark: *<@#{actioner_id}> approved this request*\n"
|
55
24
|
text += "Result:\n"
|
@@ -60,22 +29,14 @@ module Banacle
|
|
60
29
|
render_replacing_message(text)
|
61
30
|
end
|
62
31
|
|
63
|
-
def render_rejected_message
|
64
|
-
unless valid_rejector?
|
65
|
-
return self.render_error("you cannot reject the request by yourself")
|
66
|
-
end
|
67
|
-
|
32
|
+
def render_rejected_message
|
68
33
|
text = original_message_text
|
69
34
|
text += ":no_entry_sign: *<@#{actioner_id}> rejected this request*"
|
70
35
|
|
71
36
|
render_replacing_message(text)
|
72
37
|
end
|
73
38
|
|
74
|
-
def render_cancelled_message
|
75
|
-
unless valid_canceller?
|
76
|
-
return self.render_error("you cannot cancel the request by other than the requester")
|
77
|
-
end
|
78
|
-
|
39
|
+
def render_cancelled_message
|
79
40
|
text = original_message_text
|
80
41
|
text += "\nThe request was cancelled."
|
81
42
|
|
@@ -90,36 +51,12 @@ module Banacle
|
|
90
51
|
).to_json
|
91
52
|
end
|
92
53
|
|
93
|
-
def valid_approver?
|
94
|
-
ENV['BANACLE_SKIP_VALIDATION'] || !self_actioned?
|
95
|
-
end
|
96
|
-
|
97
|
-
def valid_rejector?
|
98
|
-
ENV['BANACLE_SKIP_VALIDATION'] || !self_actioned?
|
99
|
-
end
|
100
|
-
|
101
|
-
def valid_canceller?
|
102
|
-
ENV['BANACLE_SKIP_VALIDATION'] || self_actioned?
|
103
|
-
end
|
104
|
-
|
105
|
-
def self_actioned?
|
106
|
-
requester_id == actioner_id
|
107
|
-
end
|
108
|
-
|
109
|
-
def requester_id
|
110
|
-
original_message_text.match(/\A<@([^>]+)>/)[1]
|
111
|
-
end
|
112
|
-
|
113
|
-
def actioner_id
|
114
|
-
payload[:user][:id]
|
115
|
-
end
|
116
|
-
|
117
54
|
def original_message_text
|
118
|
-
|
55
|
+
request.original_message_text
|
119
56
|
end
|
120
57
|
|
121
|
-
def
|
122
|
-
|
58
|
+
def actioner_id
|
59
|
+
request.actioner_id
|
123
60
|
end
|
124
61
|
end
|
125
62
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Banacle
|
2
|
+
module InteractiveMessage
|
3
|
+
class Request
|
4
|
+
REQUESTER_ID_REGEX = /\A<@([^>]+)>/.freeze
|
5
|
+
|
6
|
+
def initialize(request)
|
7
|
+
@request = request
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :request
|
11
|
+
|
12
|
+
def action
|
13
|
+
Slack::Action.new(payload["actions"].first)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self_actioned?
|
17
|
+
requester_id == actioner_id
|
18
|
+
end
|
19
|
+
|
20
|
+
def requester_id
|
21
|
+
original_message_text.match(REQUESTER_ID_REGEX)[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def actioner_id
|
25
|
+
payload["user"]["id"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def original_message_text
|
29
|
+
payload["original_message"]["text"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def payload
|
33
|
+
@payload ||= JSON.parse(request.params["payload"])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -5,10 +5,12 @@ module Banacle
|
|
5
5
|
class SlackValidator
|
6
6
|
SLACK_SIGNING_SECRET_VERSION = 'v0'.freeze
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def initialize(signing_secret)
|
9
|
+
@signing_secret = signing_secret
|
10
10
|
end
|
11
11
|
|
12
|
+
attr_reader :signing_secret
|
13
|
+
|
12
14
|
def valid_signature?(request)
|
13
15
|
body = request.env["rack.request.form_vars"]
|
14
16
|
slack_signature = request.env["HTTP_X_SLACK_SIGNATURE"]
|
@@ -24,9 +26,5 @@ module Banacle
|
|
24
26
|
|
25
27
|
slack_signature == "#{SLACK_SIGNING_SECRET_VERSION}=#{digest}"
|
26
28
|
end
|
27
|
-
|
28
|
-
def signing_secret
|
29
|
-
ENV.fetch('BANACLE_SLACK_SIGNING_SECRET')
|
30
|
-
end
|
31
29
|
end
|
32
30
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'banacle/slash_command/error'
|
2
|
+
|
3
|
+
module Banacle
|
4
|
+
module SlashCommand
|
5
|
+
class Authenticator
|
6
|
+
class NotAuthenticatedError < Error; end
|
7
|
+
|
8
|
+
# override to implement the original validation
|
9
|
+
def authenticate_requester!(request)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,29 +1,48 @@
|
|
1
|
-
require 'banacle/
|
1
|
+
require 'banacle/slack_validator'
|
2
|
+
require 'banacle/slash_command/authenticator'
|
2
3
|
require 'banacle/slash_command/error'
|
3
4
|
require 'banacle/slash_command/parser'
|
4
5
|
require 'banacle/slash_command/renderer'
|
6
|
+
require 'banacle/slash_command/request'
|
5
7
|
|
6
8
|
module Banacle
|
7
9
|
module SlashCommand
|
8
|
-
class Handler
|
9
|
-
def
|
10
|
-
|
11
|
-
|
10
|
+
class Handler
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :config
|
16
|
+
|
17
|
+
def handle(raw_request)
|
18
|
+
unless slack_validator.valid_signature?(raw_request)
|
19
|
+
return [401, {}, "invalid signagure"]
|
12
20
|
end
|
13
21
|
|
22
|
+
request = Request.new(raw_request)
|
23
|
+
|
14
24
|
begin
|
15
|
-
|
25
|
+
authenticate_requester!(request)
|
26
|
+
command = Parser.parse(request.text)
|
16
27
|
rescue Error => e
|
17
28
|
return Renderer.render_error(e)
|
18
29
|
end
|
19
30
|
|
20
|
-
Renderer.
|
31
|
+
Renderer.new(request, command, config).render_approval_request
|
21
32
|
end
|
22
33
|
|
23
34
|
private
|
24
35
|
|
25
|
-
def
|
26
|
-
|
36
|
+
def slack_validator
|
37
|
+
@slack_validator ||= SlackValidator.new(config[:slack_signing_secret])
|
38
|
+
end
|
39
|
+
|
40
|
+
def authenticate_requester!(request)
|
41
|
+
auth.authenticate_requester!(request)
|
42
|
+
end
|
43
|
+
|
44
|
+
def auth
|
45
|
+
(config.dig(:slash_command, :authenticator) || Authenticator).new
|
27
46
|
end
|
28
47
|
end
|
29
48
|
end
|
@@ -1,18 +1,8 @@
|
|
1
1
|
require 'banacle/slack'
|
2
|
-
require 'banacle/slash_command/builder'
|
3
|
-
require 'banacle/slash_command/command'
|
4
2
|
|
5
3
|
module Banacle
|
6
4
|
module SlashCommand
|
7
5
|
class Renderer
|
8
|
-
def self.render(params, command)
|
9
|
-
new(params, command).render
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.render_unauthenticated
|
13
|
-
render_error("you are not authorized to perform this command")
|
14
|
-
end
|
15
|
-
|
16
6
|
def self.render_error(error)
|
17
7
|
Slack::Response.new(
|
18
8
|
response_type: "ephemeral",
|
@@ -20,16 +10,13 @@ module Banacle
|
|
20
10
|
).to_json
|
21
11
|
end
|
22
12
|
|
23
|
-
def initialize(
|
24
|
-
@
|
13
|
+
def initialize(request, command, config)
|
14
|
+
@request = request
|
25
15
|
@command = command
|
16
|
+
@config = config
|
26
17
|
end
|
27
18
|
|
28
|
-
attr_reader :
|
29
|
-
|
30
|
-
def render
|
31
|
-
render_approval_request
|
32
|
-
end
|
19
|
+
attr_reader :request, :command, :config
|
33
20
|
|
34
21
|
def render_approval_request
|
35
22
|
text = <<-EOS
|
@@ -44,7 +31,7 @@ module Banacle
|
|
44
31
|
text: text,
|
45
32
|
attachments: [
|
46
33
|
Slack::Attachment.new(
|
47
|
-
text: "*Approval Request*",
|
34
|
+
text: config.dig(:approval_request, :attachment, :text) || "*Approval Request*",
|
48
35
|
fallback: "TBD",
|
49
36
|
callback_id: "banacle_approval_request",
|
50
37
|
color: "#3AA3E3",
|
@@ -60,7 +47,7 @@ module Banacle
|
|
60
47
|
end
|
61
48
|
|
62
49
|
def user_id
|
63
|
-
|
50
|
+
request.user_id
|
64
51
|
end
|
65
52
|
end
|
66
53
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Banacle
|
2
|
+
module SlashCommand
|
3
|
+
class Request
|
4
|
+
def initialize(request)
|
5
|
+
@request = request
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :request
|
9
|
+
|
10
|
+
def user_id
|
11
|
+
params["user_id"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def text
|
15
|
+
params["text"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def params
|
19
|
+
request.params
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/banacle/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: banacle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takuya Kosugiyama
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -147,26 +147,30 @@ files:
|
|
147
147
|
- docs/nacl.png
|
148
148
|
- example/Gemfile
|
149
149
|
- example/Gemfile.lock
|
150
|
+
- example/README.md
|
150
151
|
- example/config.ru
|
151
152
|
- lib/banacle.rb
|
152
153
|
- lib/banacle/app.rb
|
153
|
-
- lib/banacle/authenticator.rb
|
154
154
|
- lib/banacle/aws_wrapper/error.rb
|
155
155
|
- lib/banacle/aws_wrapper/nacl.rb
|
156
156
|
- lib/banacle/aws_wrapper/result.rb
|
157
157
|
- lib/banacle/aws_wrapper/vpc.rb
|
158
|
-
- lib/banacle/
|
158
|
+
- lib/banacle/config.rb
|
159
|
+
- lib/banacle/interactive_message/authenticator.rb
|
159
160
|
- lib/banacle/interactive_message/handler.rb
|
160
161
|
- lib/banacle/interactive_message/parser.rb
|
161
162
|
- lib/banacle/interactive_message/renderer.rb
|
163
|
+
- lib/banacle/interactive_message/request.rb
|
162
164
|
- lib/banacle/slack.rb
|
163
165
|
- lib/banacle/slack_validator.rb
|
166
|
+
- lib/banacle/slash_command/authenticator.rb
|
164
167
|
- lib/banacle/slash_command/builder.rb
|
165
168
|
- lib/banacle/slash_command/command.rb
|
166
169
|
- lib/banacle/slash_command/error.rb
|
167
170
|
- lib/banacle/slash_command/handler.rb
|
168
171
|
- lib/banacle/slash_command/parser.rb
|
169
172
|
- lib/banacle/slash_command/renderer.rb
|
173
|
+
- lib/banacle/slash_command/request.rb
|
170
174
|
- lib/banacle/version.rb
|
171
175
|
homepage: https://github.com/itkq/banacle
|
172
176
|
licenses: []
|
data/lib/banacle/handler.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'banacle/authenticator'
|
2
|
-
require 'banacle/slack_validator'
|
3
|
-
|
4
|
-
module Banacle
|
5
|
-
class Handler
|
6
|
-
class InvalidAuthenticatorError < StandardError; end
|
7
|
-
|
8
|
-
attr_reader :request, :auth
|
9
|
-
|
10
|
-
def handle(request)
|
11
|
-
@request = request
|
12
|
-
|
13
|
-
unless skip_validation? || SlackValidator.valid_signature?(request)
|
14
|
-
return [401, {}, "invalid request"]
|
15
|
-
end
|
16
|
-
|
17
|
-
handle_request
|
18
|
-
end
|
19
|
-
|
20
|
-
# override
|
21
|
-
def handle_request
|
22
|
-
end
|
23
|
-
|
24
|
-
def set_authenticator!(auth)
|
25
|
-
unless auth.is_a?(Banacle::Authenticator)
|
26
|
-
raise InvalidAuthenticatorError.new(auth.inspect)
|
27
|
-
end
|
28
|
-
|
29
|
-
@auth = auth
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def authenticated?
|
35
|
-
if auth && !auth.authenticate(request)
|
36
|
-
return false
|
37
|
-
end
|
38
|
-
|
39
|
-
true
|
40
|
-
end
|
41
|
-
|
42
|
-
def skip_validation?
|
43
|
-
request.params["skip_validation"] || ENV["BANACLE_SKIP_VALIDATION"]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|