Class: SlackRubyBotAuthorization::Roles

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/slack_ruby_bot_authorization/roles.rb

Overview

The main API for handling authorization. See documentation for SlackRubyBotAuthorization top-level module.

Constant Summary

Constants included from Utils

Utils::EmptyDenialProc

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#extract_command, #extract_details, #extract_user, #normalize_string

Constructor Details

#initializeRoles

Returns a new instance of Roles.



9
10
11
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 9

def initialize
  reset!
end

Instance Attribute Details

#commandsObject (readonly)

Returns the value of attribute commands.



7
8
9
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 7

def commands
  @commands
end

Instance Method Details

#add_commands_to_role(role_name, *commands) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 81

def add_commands_to_role(role_name, *commands)
  if commands.any? { |command| command.is_a?(Array) }
    raise(ArrayArgumentException, '+commands+ argument should not\
    be an array! Try prepending argument with splat \'*\'')
  end

  role = find_role(role_name) || new_role(role_name)
  commands = @commands.find_or_make(*commands)
  role.add_commands(*commands)
  role
end

#add_default_denial_handler(aproc) ⇒ Object

Default denial proc called when a role doesn’t have a specific denial handler set.

When the specific role has its own handler, that handler may return true to allow the default handler to also run. To prevent the default handler from running, the role-specific denial handler should return false.



58
59
60
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 58

def add_default_denial_handler(aproc)
  @commands.add_default_denial_handler(aproc)
end

#add_users_to_role(role_name, *users) ⇒ Object



70
71
72
73
74
75
76
77
78
79
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 70

def add_users_to_role(role_name, *users)
  if users.any? { |user| user.is_a?(Array) }
    raise(ArrayArgumentException, '+users+ argument should not be an array!\
    Try prepending argument with splat \'*\'')
  end

  role = find_role(role_name) || new_role(role_name)
  role.add_users(*users)
  role
end

#call_default_denial_handler(client, data, match) ⇒ Object



66
67
68
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 66

def call_default_denial_handler(client, data, match)
  default_denial_handler.call(client, data, match)
end

#command_namesObject



48
49
50
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 48

def command_names
  @roles.values.inject([]) { |a, e| a + e.command_names }.uniq.sort
end

#default_denial_handlerObject



62
63
64
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 62

def default_denial_handler
  @commands.default_denial_handler
end

#find_command(command_string) ⇒ Object



36
37
38
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 36

def find_command(command_string)
  @commands.find(command_string)
end

#find_for(user_string, command_string) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 23

def find_for(user_string, command_string)
  command = find_command(command_string)
  _, found_role = @roles.find do |_name, role|
    role.user?(user_string) && role.command?(command)
  end

  found_role
end

#find_role(role_name) ⇒ Object



32
33
34
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 32

def find_role(role_name)
  @roles[normalize_string(role_name)]
end

#missing_bot_commandsObject

The complement to #unauthorized_commands. This returns an array of command names that have been authorized to a role but do NOT exist in any bot Command class.



136
137
138
139
140
141
142
143
144
145
146
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 136

def missing_bot_commands
  missing_commands = []

  command_names.each do |command_symbol|
    next if command_matches_any_route?(command_subclass_routes, command_symbol)

    # No route found for this command!
    missing_commands << command_symbol.to_s
  end
  missing_commands
end

#new_role(role_name, &blk) ⇒ Object



18
19
20
21
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 18

def new_role(role_name, &blk)
  role_name = normalize_string(role_name)
  @roles[role_name] = Role.new(role_name, &blk)
end

#remove_commands_from_role(role_name, *commands) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 102

def remove_commands_from_role(role_name, *commands)
  role = find_role(role_name)
  raise(UnknownRoleException, "No role named '#{role_name}'") unless role

  commands = @commands.find_or_make(*commands)
  role.remove_commands(*commands)
  @roles.delete(role.name) if role.commands.empty?
  role
end

#remove_users_from_role(role_name, *users) ⇒ Object



93
94
95
96
97
98
99
100
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 93

def remove_users_from_role(role_name, *users)
  role = find_role(role_name)
  raise(UnknownRoleException, "No role named '#{role_name}'") unless role

  role.remove_users(*users)
  @roles.delete(role.name) if role.users.empty?
  role
end

#reset!Object



13
14
15
16
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 13

def reset!
  @roles = {}
  @commands = Commands.new
end

#role_namesObject



40
41
42
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 40

def role_names
  @roles.values.map(&:name).uniq.sort
end

#unauthorized_commandsObject

Compares all of the commands registered to a role to a list of all custom commands. Any custom command that has not been added to a role is listed.

Use this for detecting possible mispellings between the Command classes and the authorization setup. Useful for cases where there are dozens of commands and many roles where a manual audit would be difficult.



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 120

def unauthorized_commands
  missing_commands = []

  command_subclass_routes.each do |route|
    next if route_matches_any_command?(route, command_names)

    # command did NOT match a route, therefore the command has not
    # been authorized and is orphaned
    missing_commands += commands_from_route(route)
  end
  missing_commands
end

#user_namesObject



44
45
46
# File 'lib/slack_ruby_bot_authorization/roles.rb', line 44

def user_names
  @roles.values.inject([]) { |a, e| a + e.users }.uniq.sort
end