lita-confirmation 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e2c924f5bde1d77a7df72e5a9c2740a4938741b2
4
+ data.tar.gz: b1ca21f9a0768bf904d13f05c1f8efb0d9f252b5
5
+ SHA512:
6
+ metadata.gz: 3d15be8fb17d7b2bc78f99494e77030c5b330dba303dfb077df3c79173c9144a56661ad84a93258aeb40887b4d6e8790a7dcc9cd03fc876e9a4be3cd60047c25
7
+ data.tar.gz: 01fb383bd4ebbdf4c50692abf78f0036b6a0e8cc16fb7ee0b577fe462e93b710ea89c2ede3046b481a15e891964870afc01e0a1ed42de8524f51b6b048744220
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script: bundle exec rake
5
+ before_install:
6
+ - gem update --system
7
+ services:
8
+ - redis-server
9
+ notifications:
10
+ webhooks:
11
+ urls:
12
+ - https://lita-freenode.herokuapp.com/travis
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014 Jimmy Cuadra
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,92 @@
1
+ # lita-confirmation
2
+
3
+ [![Build Status](https://travis-ci.org/jimmycuadra/lita-confirmation.png?branch=master)](https://travis-ci.org/jimmycuadra/lita-confirmation)
4
+ [![Code Climate](https://codeclimate.com/github/jimmycuadra/lita-confirmation.png)](https://codeclimate.com/github/jimmycuadra/lita-confirmation)
5
+ [![Coverage Status](https://coveralls.io/repos/jimmycuadra/lita-confirmation/badge.png)](https://coveralls.io/r/jimmycuadra/lita-confirmation)
6
+
7
+ **lita-confirmation** is an extension for [Lita](https://www.lita.io/) that allows handler routes to require "confirmation" before being triggered. Confirmation consists of a second message sent to the robot with a confirmation code.
8
+
9
+ ## Installation
10
+
11
+ Add lita-confirmation to your Lita plugin's gemspec:
12
+
13
+ ``` ruby
14
+ spec.add_runtime_dependency "lita-confirmation"
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Basic confirmation
20
+
21
+ For basic confirmation, simply set the `:confirmation` option to true when defining a route.
22
+
23
+ ``` ruby
24
+ route /danger/, :danger, command: true, confirmation: true
25
+ ```
26
+
27
+ This will result in the following behavior:
28
+
29
+ ```
30
+ Alice: Lita, danger
31
+ Lita: This command requires confirmation. To confirm, send the command "confirm 636f308"
32
+ Alice: Lita, confirm 636f308
33
+ Lita: Dangerous command executed!
34
+ ```
35
+
36
+ ### Customized confirmation
37
+
38
+ There are a few different options that can be supplied to customize the way the confirmation behaves. To supply one or more options, pass a hash as the value for the `:confirmation` option instead of just a boolean.
39
+
40
+ #### allow_self
41
+
42
+ By default, the same user who initially triggered the command can confirm it. If you want to make it even harder to trigger a command accidentally, you can require that another user send the confirmation command by setting the `:allow_self` option to false.
43
+
44
+ ``` ruby
45
+ route /danger/, :danger, command: true, confirmation: { allow_self: false }
46
+ ```
47
+
48
+ ```
49
+ Alice: Lita, danger
50
+ Lita: This command requires confirmation. To confirm, send the command "confirm 636f308"
51
+ Alice: Lita, confirm 636f308
52
+ Lita: Confirmation 636f308 must come from a different user.
53
+ Bob: Lita, confirm 636f308
54
+ Lita: Dangerous command executed!
55
+ ```
56
+
57
+ #### restrict_to
58
+
59
+ If you want to require that the confirming user be a member of a particular authorization group, use the `:restrict_to` option. The value can be either a string, a symbol, or an array or strings/symbols.
60
+
61
+ ``` ruby
62
+ route /danger/, :danger, command: true, confirmation: { restrict_to: :managers }
63
+ ```
64
+
65
+ ```
66
+ Alice: Lita, danger
67
+ Lita: This command requires confirmation. To confirm, send the command "confirm 636f308"
68
+ Alice: Lita, confirm 636f308
69
+ Lita: Confirmation 636f308 must come from a user in one of the following authorization groups: managers
70
+ Manager: Lita, confirm 636f308
71
+ Lita: Dangerous command executed!
72
+ ```
73
+
74
+ #### expire_after
75
+
76
+ By default, a confirmation must be made within one minute of the original command. After the expiry period, the original command must be sent again, and a new confirmation code will be generated. To change the length of the expiry, set the `:expire_after` value to an integer or string number of seconds.
77
+
78
+ ``` ruby
79
+ route /danger/, :danger, command: true, confirmation: { expire_after: 10 }
80
+ ```
81
+
82
+ ```
83
+ Alice: Lita, danger
84
+ Lita: This command requires confirmation. To confirm, send the command "confirm 636f308"
85
+ Alice: Waiting 15 seconds...
86
+ Alice: Lita, confirm 636f308
87
+ Lita: 636f308 is not a valid confirmation code. It may have expired. Please run the original command agin.
88
+ ```
89
+
90
+ ## License
91
+
92
+ [MIT](http://opensource.org/licenses/MIT)
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,11 @@
1
+ require "securerandom"
2
+
3
+ require "lita"
4
+
5
+ Lita.load_locales Dir[File.expand_path(
6
+ File.join("..", "..", "locales", "*.yml"), __FILE__
7
+ )]
8
+
9
+ require "lita/handlers/confirmation"
10
+ require "lita/extensions/confirmation/unconfirmed_command"
11
+ require "lita/extensions/confirmation"
@@ -0,0 +1,40 @@
1
+ module Lita
2
+ module Extensions
3
+ class Confirmation
4
+ attr_reader :handler, :message, :robot, :route
5
+
6
+ def self.call(payload)
7
+ new(
8
+ payload.fetch(:handler),
9
+ payload.fetch(:message),
10
+ payload.fetch(:robot),
11
+ payload.fetch(:route)
12
+ ).call
13
+ end
14
+
15
+ def initialize(handler, message, robot, route)
16
+ @handler = handler
17
+ @message = message
18
+ @robot = robot
19
+ @route = route
20
+ end
21
+
22
+ def call
23
+ if (options = route.extensions[:confirmation])
24
+ message.reply(
25
+ I18n.t(
26
+ "lita.extensions.confirmation.request",
27
+ code: UnconfirmedCommand.new(handler, message, robot, route, options).code
28
+ )
29
+ )
30
+
31
+ return false
32
+ end
33
+
34
+ true
35
+ end
36
+ end
37
+
38
+ Lita.register_hook(:validate_route, Confirmation)
39
+ end
40
+ end
@@ -0,0 +1,77 @@
1
+ require "securerandom"
2
+
3
+ module Lita
4
+ module Extensions
5
+ class Confirmation
6
+ class UnconfirmedCommand
7
+ attr_reader :allow_self, :code, :groups, :handler, :message, :robot, :route, :timer_thread
8
+
9
+ class << self
10
+ def find(code)
11
+ confirmations[code]
12
+ end
13
+
14
+ def confirmations
15
+ @confirmations ||= {}
16
+ end
17
+
18
+ def reset
19
+ confirmations.clear
20
+ end
21
+ end
22
+
23
+ def initialize(handler, message, robot, route, options)
24
+ @handler = handler
25
+ @message = message
26
+ @robot = robot
27
+ @route = route
28
+
29
+ @code = SecureRandom.hex(3)
30
+
31
+ self.class.confirmations[code] = self
32
+
33
+ process_options(options)
34
+ end
35
+
36
+ def call(user)
37
+ return :other_user_required if disallow_self?(user)
38
+ return :user_in_group_required unless in_required_group?(user)
39
+
40
+ expire
41
+ timer_thread.kill if timer_thread
42
+ handler.dispatch_to_route(route, robot, message)
43
+ end
44
+
45
+ private
46
+
47
+ def disallow_self?(confirming_user)
48
+ true if !allow_self && message.user == confirming_user
49
+ end
50
+
51
+ def expire
52
+ self.class.confirmations.delete(code)
53
+ end
54
+
55
+ def in_required_group?(user)
56
+ return true unless groups
57
+
58
+ groups.any? { |group| Lita::Authorization.user_in_group?(user, group) }
59
+ end
60
+
61
+ def process_options(options)
62
+ options = Hash === options ? options : {}
63
+
64
+ @allow_self = options.key?(:allow_self) ? options[:allow_self] : true
65
+ @groups = options.key?(:restrict_to) ? Array(options[:restrict_to]) : nil
66
+
67
+ expiry = options.key?(:expire_after) ? options[:expire_after] : 60
68
+ @timer_thread = Thread.new do
69
+ Lita::Timer.new(interval: expiry) do
70
+ expire
71
+ end.start
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,36 @@
1
+ module Lita
2
+ module Handlers
3
+ class Confirmation < Handler
4
+ route /^confirm\s+([a-f0-9]{6})$/i, :confirm, command: true, help: {
5
+ t("help.key") => t("help.value")
6
+ }
7
+
8
+ def confirm(response)
9
+ code = response.matches[0][0]
10
+
11
+ command = Extensions::Confirmation::UnconfirmedCommand.find(code)
12
+
13
+ if command
14
+ call_command(command, code, response)
15
+ else
16
+ response.reply(t("invalid_code", code: code))
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def call_command(command, code, response)
23
+ case command.call(response.user)
24
+ when :other_user_required
25
+ response.reply(t("other_user_required", code: code))
26
+ when :user_in_group_required
27
+ response.reply(
28
+ t("user_in_group_required", code: code, groups: command.groups.join(", "))
29
+ )
30
+ end
31
+ end
32
+ end
33
+
34
+ Lita.register_handler(Confirmation)
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "lita-confirmation"
3
+ spec.version = "0.0.1"
4
+ spec.authors = ["Jimmy Cuadra"]
5
+ spec.email = ["jimmy@jimmycuadra.com"]
6
+ spec.description = %q{A Lita extension to require confirmation for commands.}
7
+ spec.summary = %q{A Lita extension to require confirmation for potentially dangerous commands.}
8
+ spec.homepage = "https://github.com/jimmycuadra/lita-confirmation"
9
+ spec.license = "MIT"
10
+ spec.metadata = { "lita_plugin_type" => "extension" }
11
+
12
+ spec.files = `git ls-files`.split($/)
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_runtime_dependency "lita", ">= 3.3"
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.3"
20
+ spec.add_development_dependency "rake"
21
+ spec.add_development_dependency "rspec", ">= 3.0.0.beta2"
22
+ spec.add_development_dependency "simplecov"
23
+ spec.add_development_dependency "coveralls"
24
+ end
@@ -0,0 +1,13 @@
1
+ en:
2
+ lita:
3
+ extensions:
4
+ confirmation:
5
+ request: This command requires confirmation. To confirm, send the command "confirm %{code}"
6
+ handlers:
7
+ confirmation:
8
+ help:
9
+ key: confirm CODE
10
+ value: Confirms a previously sent command with the confirmation code CODE.
11
+ invalid_code: "%{code} is not a valid confirmation code. It may have expired. Please run the original command agin."
12
+ other_user_required: "Confirmation %{code} must come from a different user."
13
+ user_in_group_required: "Confirmation %{code} must come from a user in one of the following authorization groups: %{groups}"
@@ -0,0 +1,125 @@
1
+ require "spec_helper"
2
+
3
+ class Dangerous < Lita::Handler
4
+ route /^danger$/, :danger, command: true, confirmation: true
5
+ route /^danger self$/, :disallow_self, command: true, confirmation: { allow_self: false }
6
+ route(
7
+ /^danger restrict$/,
8
+ :require_auth_group,
9
+ command: true,
10
+ confirmation: { restrict_to: :managers }
11
+ )
12
+ route /^danger expire$/, :expire_early, command: true, confirmation: { expire_after: 0 }
13
+
14
+ def danger(response)
15
+ response.reply("Dangerous command executed!")
16
+ end
17
+
18
+ def disallow_self(response)
19
+ response.reply("Dangerous command confirmed by another user and executed!")
20
+ end
21
+
22
+ def require_auth_group(response)
23
+ response.reply("Dangerous command confirmed by a manager!")
24
+ end
25
+
26
+ def expire_early(response)
27
+ response.reply("Dangerous command executed within 0 seconds!")
28
+ end
29
+ end
30
+
31
+ describe Dangerous, lita_handler: true do
32
+ before do
33
+ allow(Lita).to receive(:handlers).and_return([described_class, Lita::Handlers::Confirmation])
34
+ Lita::Extensions::Confirmation::UnconfirmedCommand.reset
35
+ end
36
+
37
+ context "with confirmation: true" do
38
+ it "requires confirmation" do
39
+ send_command("danger")
40
+ expect(replies.last).to match(/send the command "confirm [a-f0-9]{6}"/)
41
+ end
42
+
43
+ it "invokes the original route on confirmation" do
44
+ send_command("danger")
45
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
46
+ send_command("confirm #{code}")
47
+ expect(replies.last).to eq("Dangerous command executed!")
48
+ end
49
+
50
+ it "expires when confirmed" do
51
+ send_command("danger")
52
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
53
+ send_command("confirm #{code}")
54
+ send_command("confirm #{code}")
55
+ expect(replies.last).to include("not a valid confirmation code")
56
+ end
57
+
58
+ it "responds with a message when an invalid code is provided" do
59
+ send_command("danger")
60
+ send_command("confirm 000000")
61
+ expect(replies.last).to include("000000 is not a valid confirmation code")
62
+ end
63
+ end
64
+
65
+ context "with allow_self: false" do
66
+ it "responds with a message if the user tries to confirm their own command" do
67
+ send_command("danger self")
68
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
69
+ send_command("confirm #{code}")
70
+ expect(replies.last).to include("must come from a different user")
71
+ end
72
+
73
+ it "invokes the original route on confirmation by another user" do
74
+ send_command("danger self")
75
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
76
+ send_command("confirm #{code}", as: Lita::User.create(123))
77
+ expect(replies.last).to eq("Dangerous command confirmed by another user and executed!")
78
+ end
79
+ end
80
+
81
+ context "with restrict_to: :managers" do
82
+ let(:manager) do
83
+ manager = Lita::User.create(123)
84
+ allow(Lita::Authorization).to receive(:user_in_group?).with(
85
+ manager, :managers
86
+ ).and_return(true)
87
+ manager
88
+ end
89
+
90
+ it "responds with a message if a user not in a required group tries to confirm a command" do
91
+ send_command("danger restrict")
92
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
93
+ send_command("confirm #{code}")
94
+ expect(replies.last).to include(
95
+ "must come from a user in one of the following authorization groups: managers"
96
+ )
97
+ end
98
+
99
+ it "invokes the original route on confirmation by a manager" do
100
+ send_command("danger restrict")
101
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
102
+ send_command("confirm #{code}", as: manager)
103
+ expect(replies.last).to include("confirmed by a manager")
104
+ end
105
+ end
106
+
107
+ context "with expire_after: 0" do
108
+ before { allow(Thread).to receive(:new) }
109
+
110
+ it "invokes the original route on confirmation within the expiry" do
111
+ send_command("danger expire")
112
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
113
+ send_command("confirm #{code}")
114
+ expect(replies.last).to include("within 0 seconds")
115
+ end
116
+
117
+ it "responds that the code is invalid after 0 seconds" do
118
+ allow(Thread).to receive(:new).and_yield
119
+ send_command("danger expire")
120
+ code = replies.last.match(/([a-f0-9]{6})"$/)[1]
121
+ send_command("confirm #{code}")
122
+ expect(replies.last).to include("not a valid confirmation code")
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,10 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4
+ SimpleCov::Formatter::HTMLFormatter,
5
+ Coveralls::SimpleCov::Formatter
6
+ ]
7
+ SimpleCov.start { add_filter "/spec/" }
8
+
9
+ require "lita-confirmation"
10
+ require "lita/rspec"
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-confirmation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jimmy Cuadra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0.beta2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 3.0.0.beta2
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: A Lita extension to require confirmation for commands.
98
+ email:
99
+ - jimmy@jimmycuadra.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".travis.yml"
106
+ - Gemfile
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - lib/lita-confirmation.rb
111
+ - lib/lita/extensions/confirmation.rb
112
+ - lib/lita/extensions/confirmation/unconfirmed_command.rb
113
+ - lib/lita/handlers/confirmation.rb
114
+ - lita-confirmation.gemspec
115
+ - locales/en.yml
116
+ - spec/lita/extensions/confirmation_spec.rb
117
+ - spec/spec_helper.rb
118
+ homepage: https://github.com/jimmycuadra/lita-confirmation
119
+ licenses:
120
+ - MIT
121
+ metadata:
122
+ lita_plugin_type: extension
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.2.2
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: A Lita extension to require confirmation for potentially dangerous commands.
143
+ test_files:
144
+ - spec/lita/extensions/confirmation_spec.rb
145
+ - spec/spec_helper.rb