slack-smart-bot 1.5.1 → 1.6.0

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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +89 -2
  3. data/lib/slack-smart-bot.rb +6 -1
  4. data/lib/slack/smart-bot/commands.rb +5 -0
  5. data/lib/slack/smart-bot/commands/general/bot_help.rb +44 -40
  6. data/lib/slack/smart-bot/commands/general/bot_status.rb +32 -28
  7. data/lib/slack/smart-bot/commands/general/bye_bot.rb +9 -1
  8. data/lib/slack/smart-bot/commands/general/hi_bot.rb +6 -1
  9. data/lib/slack/smart-bot/commands/general/use_rules.rb +33 -29
  10. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +40 -35
  11. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +1 -0
  12. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +32 -0
  13. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +30 -25
  14. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +43 -0
  15. data/lib/slack/smart-bot/commands/on_bot/repl.rb +202 -0
  16. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +33 -29
  17. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +73 -0
  18. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +24 -0
  19. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +23 -18
  20. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +32 -27
  21. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +79 -74
  22. data/lib/slack/smart-bot/listen.rb +2 -0
  23. data/lib/slack/smart-bot/process.rb +61 -9
  24. data/lib/slack/smart-bot/process_first.rb +17 -3
  25. data/lib/slack/smart-bot/treat_message.rb +24 -3
  26. data/lib/slack/smart-bot/utils.rb +3 -0
  27. data/lib/slack/smart-bot/utils/get_help.rb +1 -1
  28. data/lib/slack/smart-bot/utils/get_repls.rb +11 -0
  29. data/lib/slack/smart-bot/utils/update_repls.rb +8 -0
  30. metadata +28 -19
@@ -17,46 +17,51 @@ class SlackSmartBot
17
17
  # help: _shortcut Spanish Account_
18
18
  # help: _Spanish Account_
19
19
  # help:
20
- def add_shortcut(dest, from, typem, for_all, shortcut_name, command, command_to_run)
20
+ def add_shortcut(dest, user, typem, for_all, shortcut_name, command, command_to_run)
21
21
  save_stats(__method__)
22
22
  unless typem == :on_extended
23
- @shortcuts[from] = Hash.new() unless @shortcuts.keys.include?(from)
24
-
25
- found_other = false
26
- if for_all.to_s != ""
27
- @shortcuts.each { |sck, scv|
28
- if sck != :all and sck != from and scv.key?(shortcut_name)
29
- found_other = true
30
- end
31
- }
32
- end
33
- if !config.admins.include?(from) and @shortcuts[:all].include?(shortcut_name) and !@shortcuts[from].include?(shortcut_name)
34
- respond "Only the creator of the shortcut can modify it", dest
35
- elsif found_other
36
- respond "You cannot create a shortcut for all with the same name than other user is using", dest
37
- elsif !@shortcuts[from].include?(shortcut_name)
38
- #new shortcut
39
- @shortcuts[from][shortcut_name] = command_to_run
40
- @shortcuts[:all][shortcut_name] = command_to_run if for_all.to_s != ""
41
- update_shortcuts_file()
42
- respond "shortcut added", dest
23
+ from = user.name
24
+ if config[:allow_access].key?(__method__) and !config[:allow_access][__method__].include?(user.name) and !config[:allow_access][__method__].include?(user.id)
25
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
43
26
  else
44
- #are you sure? to avoid overwriting existing
45
- unless @questions.keys.include?(from)
46
- ask("The shortcut already exists, are you sure you want to overwrite it?", command, from, dest)
27
+ @shortcuts[from] = Hash.new() unless @shortcuts.keys.include?(from)
28
+
29
+ found_other = false
30
+ if for_all.to_s != ""
31
+ @shortcuts.each { |sck, scv|
32
+ if sck != :all and sck != from and scv.key?(shortcut_name)
33
+ found_other = true
34
+ end
35
+ }
36
+ end
37
+ if !config.admins.include?(from) and @shortcuts[:all].include?(shortcut_name) and !@shortcuts[from].include?(shortcut_name)
38
+ respond "Only the creator of the shortcut can modify it", dest
39
+ elsif found_other
40
+ respond "You cannot create a shortcut for all with the same name than other user is using", dest
41
+ elsif !@shortcuts[from].include?(shortcut_name)
42
+ #new shortcut
43
+ @shortcuts[from][shortcut_name] = command_to_run
44
+ @shortcuts[:all][shortcut_name] = command_to_run if for_all.to_s != ""
45
+ update_shortcuts_file()
46
+ respond "shortcut added", dest
47
47
  else
48
- case @questions[from]
49
- when /^(yes|yep)/i
50
- @shortcuts[from][shortcut_name] = command_to_run
51
- @shortcuts[:all][shortcut_name] = command_to_run if for_all.to_s != ""
52
- update_shortcuts_file()
53
- respond "shortcut added", dest
54
- @questions.delete(from)
55
- when /^no/i
56
- respond "ok, I won't add it", dest
57
- @questions.delete(from)
48
+ #are you sure? to avoid overwriting existing
49
+ unless @questions.keys.include?(from)
50
+ ask("The shortcut already exists, are you sure you want to overwrite it?", command, from, dest)
58
51
  else
59
- ask "I don't understand, yes or no?", command, from, dest
52
+ case @questions[from]
53
+ when /^(yes|yep)/i
54
+ @shortcuts[from][shortcut_name] = command_to_run
55
+ @shortcuts[:all][shortcut_name] = command_to_run if for_all.to_s != ""
56
+ update_shortcuts_file()
57
+ respond "shortcut added", dest
58
+ @questions.delete(from)
59
+ when /^no/i
60
+ respond "ok, I won't add it", dest
61
+ @questions.delete(from)
62
+ else
63
+ ask "I don't understand, yes or no?", command, from, dest
64
+ end
60
65
  end
61
66
  end
62
67
  end
@@ -22,6 +22,7 @@ class SlackSmartBot
22
22
  else
23
23
  ruby = ""
24
24
  end
25
+ started = Time.now
25
26
  process_to_run = "#{ruby}#{Dir.pwd}#{@routines[@channel_id][name][:file_path][1..-1]}"
26
27
  process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
27
28
 
@@ -0,0 +1,32 @@
1
+ class SlackSmartBot
2
+ # help: ----------------------------------------------
3
+ # help: `delete repl SESSION_NAME`
4
+ # help: `delete irb SESSION_NAME`
5
+ # help: `remove repl SESSION_NAME`
6
+ # help:
7
+ # help: Will delete the specified REPL
8
+ # help: Only the creator of the REPL or an admin can delete REPLs
9
+ # help:
10
+ def delete_repl(dest, user, session_name)
11
+ #todo: add tests
12
+ save_stats(__method__)
13
+ if config[:allow_access].key?(__method__) and !config[:allow_access][__method__].include?(user.name) and !config[:allow_access][__method__].include?(user.id)
14
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
15
+ else
16
+ if @repls.key?(session_name)
17
+ Dir.mkdir("#{config.path}/repl") unless Dir.exist?("#{config.path}/repl")
18
+ if config.admins.include?(user.name) or @repls[session_name].creator_name == user.name
19
+ @repls.delete(session_name)
20
+ update_repls()
21
+ File.rename("#{config.path}/repl/#{@channel_id}/#{session_name}.input", "#{config.path}/repl/#{@channel_id}/#{session_name}_#{Time.now.strftime("%Y%m%d%H%M%S%N")}.deleted")
22
+ respond "REPL #{session_name} deleted"
23
+ else
24
+ respond "Only admins or the creator of this REPL can delete it", dest
25
+ end
26
+
27
+ else
28
+ respond "The REPL with session name: #{session_name} doesn't exist on this Smart Bot Channel", dest
29
+ end
30
+ end
31
+ end
32
+ end
@@ -5,37 +5,42 @@ class SlackSmartBot
5
5
  # help: It will delete the shortcut with the supplied name
6
6
  # help:
7
7
 
8
- def delete_shortcut(dest, from, shortcut, typem, command)
8
+ def delete_shortcut(dest, user, shortcut, typem, command)
9
9
  save_stats(__method__)
10
10
  unless typem == :on_extended
11
- deleted = false
11
+ from = user.name
12
+ if config[:allow_access].key?(__method__) and !config[:allow_access][__method__].include?(user.name) and !config[:allow_access][__method__].include?(user.id)
13
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
14
+ else
15
+ deleted = false
12
16
 
13
- if !config.admins.include?(from) and @shortcuts[:all].include?(shortcut) and !@shortcuts[from].include?(shortcut)
14
- respond "Only the creator of the shortcut or an admin user can delete it", dest
15
- elsif (@shortcuts.keys.include?(from) and @shortcuts[from].keys.include?(shortcut)) or
16
- (config.admins.include?(from) and @shortcuts[:all].include?(shortcut))
17
- #are you sure? to avoid deleting by mistake
18
- unless @questions.keys.include?(from)
19
- ask("are you sure you want to delete it?", command, from, dest)
20
- else
21
- case @questions[from]
22
- when /^(yes|yep)/i
23
- @questions.delete(from)
24
- respond "shortcut deleted!", dest
25
- respond("#{shortcut}: #{@shortcuts[from][shortcut]}", dest) if @shortcuts.key?(from) and @shortcuts[from].key?(shortcut)
26
- respond("#{shortcut}: #{@shortcuts[:all][shortcut]}", dest) if @shortcuts.key?(:all) and @shortcuts[:all].key?(shortcut)
27
- @shortcuts[from].delete(shortcut) if @shortcuts.key?(from) and @shortcuts[from].key?(shortcut)
28
- @shortcuts[:all].delete(shortcut) if @shortcuts.key?(:all) and @shortcuts[:all].key?(shortcut)
29
- update_shortcuts_file()
30
- when /^no/i
31
- @questions.delete(from)
32
- respond "ok, I won't delete it", dest
17
+ if !config.admins.include?(from) and @shortcuts[:all].include?(shortcut) and !@shortcuts[from].include?(shortcut)
18
+ respond "Only the creator of the shortcut or an admin user can delete it", dest
19
+ elsif (@shortcuts.keys.include?(from) and @shortcuts[from].keys.include?(shortcut)) or
20
+ (config.admins.include?(from) and @shortcuts[:all].include?(shortcut))
21
+ #are you sure? to avoid deleting by mistake
22
+ unless @questions.keys.include?(from)
23
+ ask("are you sure you want to delete it?", command, from, dest)
33
24
  else
34
- ask("I don't understand, are you sure you want to delete it? (yes or no)", command, from, dest)
25
+ case @questions[from]
26
+ when /^(yes|yep)/i
27
+ @questions.delete(from)
28
+ respond "shortcut deleted!", dest
29
+ respond("#{shortcut}: #{@shortcuts[from][shortcut]}", dest) if @shortcuts.key?(from) and @shortcuts[from].key?(shortcut)
30
+ respond("#{shortcut}: #{@shortcuts[:all][shortcut]}", dest) if @shortcuts.key?(:all) and @shortcuts[:all].key?(shortcut)
31
+ @shortcuts[from].delete(shortcut) if @shortcuts.key?(from) and @shortcuts[from].key?(shortcut)
32
+ @shortcuts[:all].delete(shortcut) if @shortcuts.key?(:all) and @shortcuts[:all].key?(shortcut)
33
+ update_shortcuts_file()
34
+ when /^no/i
35
+ @questions.delete(from)
36
+ respond "ok, I won't delete it", dest
37
+ else
38
+ ask("I don't understand, are you sure you want to delete it? (yes or no)", command, from, dest)
39
+ end
35
40
  end
41
+ else
42
+ respond "shortcut not found", dest
36
43
  end
37
- else
38
- respond "shortcut not found", dest
39
44
  end
40
45
  end
41
46
  end
@@ -0,0 +1,43 @@
1
+ class SlackSmartBot
2
+ # help: ----------------------------------------------
3
+ # help: `get repl SESSION_NAME`
4
+ # help: `get irb SESSION_NAME`
5
+ # help: `get live SESSION_NAME`
6
+ # help:
7
+ # help: Will get the Ruby commands sent on that SESSION_NAME.
8
+ # help:
9
+ def get_repl(dest, user, session_name)
10
+ #todo: add tests
11
+ save_stats(__method__)
12
+ if config[:allow_access].key?(__method__) and !config[:allow_access][__method__].include?(user.name) and !config[:allow_access][__method__].include?(user.id)
13
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
14
+ else
15
+ Dir.mkdir("#{config.path}/repl") unless Dir.exist?("#{config.path}/repl")
16
+ Dir.mkdir("#{config.path}/repl/#{@channel_id}") unless Dir.exist?("#{config.path}/repl/#{@channel_id}")
17
+ if File.exist?("#{config.path}/repl/#{@channel_id}/#{session_name}.input")
18
+ if @repls.key?(session_name) and @repls[session_name][:type] == :private and
19
+ @repls[session_name][:creator_name]!=user.name and
20
+ !config.admins.include?(user.name)
21
+ respond "The REPL with session name: #{session_name} is private", dest
22
+ else
23
+ if @repls.key?(session_name)
24
+ @repls[session_name][:accessed] = Time.now.to_s
25
+ @repls[session_name][:gets] += 1
26
+ update_repls()
27
+ end
28
+
29
+ content = "require 'nice_http'\n"
30
+ if File.exist?("#{project_folder}/.smart-bot-repl")
31
+ content += File.read("#{project_folder}/.smart-bot-repl")
32
+ content += "\n"
33
+ end
34
+ content += File.read("#{config.path}/repl/#{@channel_id}/#{session_name}.input").gsub(/^(quit|exit|bye)$/i,'')
35
+ File.write("#{config.path}/repl/#{@channel_id}/#{session_name}.rb", content, mode: "w+")
36
+ send_file(dest, "REPL #{session_name} on #{config.channel}", "#{config.path}/repl/#{@channel_id}/#{session_name}.rb", " REPL #{session_name} on #{config.channel}", 'text/plain', "ruby")
37
+ end
38
+ else
39
+ respond "The REPL with session name: #{session_name} doesn't exist on this Smart Bot Channel", dest
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,202 @@
1
+ class SlackSmartBot
2
+ # help: ----------------------------------------------
3
+ # help: `repl`
4
+ # help: `live`
5
+ # help: `irb`
6
+ # help: `repl SESSION_NAME`
7
+ # help: `private repl SESSION_NAME`
8
+ # help: `repl ENV_VAR=VALUE`
9
+ # help: `repl SESSION_NAME ENV_VAR=VALUE ENV_VAR='VALUE'`
10
+ # help: `repl SESSION_NAME: "DESCRIPTION"`
11
+ # help: `repl SESSION_NAME: "DESCRIPTION" ENV_VAR=VALUE ENV_VAR='VALUE'`
12
+ # help:
13
+ # help: Will run all we write as a ruby command and will keep the session values.
14
+ # help: SESSION_NAME only admits from a to Z, numbers, - and _
15
+ # help: If no SESSION_NAME supplied it will be treated as a temporary REPL
16
+ # help: If 'private' specified the repl will be accessible only by you and it will be displayed only to you when `see repls`
17
+ # help: To avoid a message to be treated, start the message with '-'.
18
+ # help: Send _quit_, _bye_ or _exit_ to finish the session.
19
+ # help: Send puts, print, p or pp if you want to print out something when using `run repl` later.
20
+ # help: After 30 minutes of no communication with the Smart Bot the session will be dismissed.
21
+ # help: If you declare on your rules file a method called `project_folder` returning the path for the project folder, the code will be executed from that folder.
22
+ # help: By default it will be automatically loaded the gems: string_pattern, nice_hash and nice_http
23
+ # help: To pre-execute some ruby when starting the session add the code to .smart-bot-repl file on the project root folder defined on project_folder
24
+ # help: If you want to see the methods of a class or module you created use _ls TheModuleOrClass_
25
+ # help: You can supply the Environmental Variables you need for the Session
26
+ # help: Examples:
27
+ # help: _repl CreateCustomer LOCATION=spain HOST='https://10.30.40.50:8887'_
28
+ # help: _repl CreateCustomer: "It creates a random customer for testing" LOCATION=spain HOST='https://10.30.40.50:8887'_
29
+ # help: _repl delete_logs_
30
+ # help: _private repl random-ssn_
31
+ # help:
32
+ def repl(dest, user, session_name, env_vars, rules_file, command, description, type)
33
+ #todo: add more tests
34
+ from = user.name
35
+ if config[:allow_access].key?(__method__) and !config[:allow_access][__method__].include?(user.name) and !config[:allow_access][__method__].include?(user.id)
36
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
37
+ else
38
+ if !@repl_sessions.key?(from)
39
+ save_stats(__method__)
40
+ Dir.mkdir("#{config.path}/repl") unless Dir.exist?("#{config.path}/repl")
41
+ Dir.mkdir("#{config.path}/repl/#{@channel_id}") unless Dir.exist?("#{config.path}/repl/#{@channel_id}")
42
+
43
+ serialt = Time.now.strftime("%Y%m%d%H%M%S%N")
44
+ if session_name.to_s==''
45
+ session_name = "#{from}_#{serialt}"
46
+ temp_repl = true
47
+ else
48
+ temp_repl = false
49
+ i = 0
50
+ name = session_name
51
+ while File.exist?("#{config.path}/repl/#{@channel_id}/#{session_name}.input")
52
+ i+=1
53
+ session_name = "#{name}#{i}"
54
+ end
55
+ end
56
+ @repl_sessions[from] = {
57
+ name: session_name,
58
+ dest: dest,
59
+ started: Time.now,
60
+ finished: Time.now,
61
+ input: [],
62
+ on_thread: Thread.current[:on_thread],
63
+ thread_ts: Thread.current[:thread_ts]
64
+ }
65
+
66
+ unless temp_repl
67
+ @repls[session_name] = {
68
+ created: @repl_sessions[from][:started].to_s,
69
+ accessed: @repl_sessions[from][:started].to_s,
70
+ creator_name: user.name,
71
+ creator_id: user.id,
72
+ description: description,
73
+ type: type,
74
+ runs_by_creator: 0,
75
+ runs_by_others: 0,
76
+ gets: 0
77
+ }
78
+ update_repls()
79
+ end
80
+
81
+ message = "Session name: *#{session_name}*
82
+ From now on I will execute all you write as a Ruby command and I will keep the session open until you send `quit` or `bye` or `exit`.
83
+ I will respond with the result so it is not necessary you send `print`, `puts`, `p` or `pp` unless you want it as the output when calling `run repl`.
84
+ If you want to avoid a message to be treated by me, start the message with '-'.
85
+ After 30 minutes of no communication with the Smart Bot the session will be dismissed.
86
+ If you want to see the methods of a class or module you created use _ls TheModuleOrClass_
87
+ You can supply the Environmental Variables you need for the Session
88
+ Example:
89
+ _repl CreateCustomer LOCATION=spain HOST='https://10.30.40.50:8887'_
90
+ "
91
+ respond message, dest
92
+
93
+ File.write("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.input", "", mode: "a+")
94
+ File.write("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.output", "", mode: "a+")
95
+
96
+ process_to_run = '
97
+ ruby -e "' + env_vars.join("\n") + '
98
+ require \"awesome_print\"
99
+ bindme' + serialt + ' = binding
100
+ eval(\"require \'nice_http\'\" , bindme' + serialt + ')
101
+
102
+ file_input_repl = File.open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.input\", \"r\")
103
+ while true do
104
+ sleep 0.2
105
+ if File.exist?(\"./.smart-bot-repl\")
106
+ begin
107
+ eval(File.read(\"./.smart-bot-repl\"), bindme' + serialt + ')
108
+ rescue Exception => resp_repl
109
+ end
110
+ end
111
+ code_to_run_repl = file_input_repl.read
112
+ if code_to_run_repl.to_s!=''
113
+ if code_to_run_repl.to_s.match?(/^quit$/i) or
114
+ code_to_run_repl.to_s.match?(/^exit$/i) or
115
+ code_to_run_repl.to_s.match?(/^bye bot$/i) or
116
+ code_to_run_repl.to_s.match?(/^bye$/i)
117
+ exit
118
+ else
119
+ if code_to_run_repl.match?(/^\s*ls\s+(.+)/)
120
+ code_to_run_repl = \"#{code_to_run_repl.scan(/^\s*ls\s+(.+)/).join}.methods - Object.methods\"
121
+ end
122
+ begin
123
+ code_to_run_repl.gsub!(/^\s*(puts|print|p|pp)\s/, \"\")
124
+ resp_repl = eval(code_to_run_repl.to_s, bindme' + serialt + ')
125
+ rescue Exception => resp_repl
126
+ end
127
+ if resp_repl.to_s != \"\"
128
+ open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
129
+ f.puts \"\`\`\`#{resp_repl.awesome_inspect}\`\`\`\"
130
+ }
131
+ end
132
+ end
133
+ end
134
+ end"
135
+ '
136
+
137
+ unless rules_file.empty? # to get the project_folder
138
+ begin
139
+ eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
140
+ end
141
+ end
142
+ started = Time.now
143
+ process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
144
+
145
+ stdin, stdout, stderr, wait_thr = Open3.popen3(process_to_run)
146
+ timeout = 30 * 60 # 30 minutes
147
+
148
+ file_output_repl = File.open("#{config.path}/repl/#{@channel_id}/#{session_name}.output", "r")
149
+
150
+ while (wait_thr.status == 'run' or wait_thr.status == 'sleep') and @repl_sessions.key?(from)
151
+ begin
152
+ if (Time.now-@repl_sessions[from][:finished]) > timeout
153
+ open("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.input", 'a+') {|f|
154
+ f.puts 'quit'
155
+ }
156
+ respond "REPL session finished: #{@repl_sessions[from][:name]}", dest
157
+ @repl_sessions.delete(from)
158
+ break
159
+ end
160
+ sleep 0.2
161
+ resp_repl = file_output_repl.read
162
+ if resp_repl.to_s!=''
163
+ respond resp_repl, dest
164
+ end
165
+ rescue Exception => excp
166
+ @logger.fatal excp
167
+ end
168
+ end
169
+ else
170
+ @repl_sessions[from][:finished] = Time.now
171
+ code = @repl_sessions[from][:command]
172
+ @repl_sessions[from][:command] = ''
173
+ code.gsub!("\\n", "\n")
174
+ code.gsub!("\\r", "\r")
175
+ # Disabled for the moment sinde it is deleting lines with '}'
176
+ #code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting.
177
+ if code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
178
+ code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
179
+ code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
180
+ code.include?("ENV") or code.match?(/=\s*IO/)
181
+ respond "Sorry I cannot run this due security reasons", dest
182
+ else
183
+ @repl_sessions[from][:input]<<code
184
+ case code
185
+ when /^\s*(quit|exit|bye|bye bot)\s*$/i
186
+ open("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.input", 'a+') {|f|
187
+ f.puts code
188
+ }
189
+ respond "REPL session finished: #{@repl_sessions[from][:name]}", dest
190
+ @repl_sessions.delete(from)
191
+ when /^\s*-/i
192
+ #ommit
193
+ else
194
+ open("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.input", 'a+') {|f|
195
+ f.puts code
196
+ }
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
@@ -7,43 +7,47 @@ class SlackSmartBot
7
7
  # help: _ruby require 'json'; res=[]; 20.times {res<<rand(100)}; my_json={result: res}; puts my_json.to_json_
8
8
  # help:
9
9
 
10
- def ruby_code(dest, code, rules_file)
10
+ def ruby_code(dest, user, code, rules_file)
11
11
  save_stats(__method__)
12
- unless code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
13
- code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
14
- code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
15
- code.include?("ENV") or code.match?(/=\s*IO/)
16
- unless rules_file.empty?
17
- begin
18
- eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
12
+ if config[:allow_access].key?(__method__) and !config[:allow_access][__method__].include?(user.name) and !config[:allow_access][__method__].include?(user.id)
13
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
14
+ else
15
+ unless code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
16
+ code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
17
+ code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
18
+ code.include?("ENV") or code.match?(/=\s*IO/)
19
+ unless rules_file.empty?
20
+ begin
21
+ eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
22
+ end
19
23
  end
20
- end
21
24
 
22
- respond "Running", dest if code.size > 100
25
+ respond "Running", dest if code.size > 100
23
26
 
24
- begin
25
- code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting
26
- ruby = "ruby -e \"#{code.gsub('"', '\"')}\""
27
- if defined?(project_folder) and project_folder.to_s != "" and Dir.exist?(project_folder)
28
- ruby = ("cd #{project_folder} &&" + ruby)
29
- else
30
- def project_folder() "" end
31
- end
32
- stdout, stderr, status = Open3.capture3(ruby)
33
- if stderr == ""
34
- if stdout == ""
35
- respond "Nothing returned. Remember you need to use p or puts to print", dest
27
+ begin
28
+ code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting
29
+ ruby = "ruby -e \"#{code.gsub('"', '\"')}\""
30
+ if defined?(project_folder) and project_folder.to_s != "" and Dir.exist?(project_folder)
31
+ ruby = ("cd #{project_folder} &&" + ruby)
32
+ else
33
+ def project_folder() "" end
34
+ end
35
+ stdout, stderr, status = Open3.capture3(ruby)
36
+ if stderr == ""
37
+ if stdout == ""
38
+ respond "Nothing returned. Remember you need to use p or puts to print", dest
39
+ else
40
+ respond stdout, dest
41
+ end
36
42
  else
37
- respond stdout, dest
43
+ respond "#{stderr}\n#{stdout}", dest
38
44
  end
39
- else
40
- respond "#{stderr}\n#{stdout}", dest
45
+ rescue Exception => exc
46
+ respond exc, dest
41
47
  end
42
- rescue Exception => exc
43
- respond exc, dest
48
+ else
49
+ respond "Sorry I cannot run this due security reasons", dest
44
50
  end
45
- else
46
- respond "Sorry I cannot run this due security reasons", dest
47
51
  end
48
52
  end
49
53
  end