UNPKG

4.54 kBtext/coffeescriptView Raw
1# Description
2# Assign roles to users and restrict command access in other scripts.
3#
4# Configuration:
5# HUBOT_AUTH_ADMIN - A comma separate list of user IDs
6#
7# Commands:
8# hubot <user> has <role> role - Assigns a role to a user
9# hubot <user> doesn't have <role> role - Removes a role from a user
10# hubot what roles does <user> have - Find out what roles a user has
11# hubot what roles do I have - Find out what roles you have
12# hubot who has <role> role - Find out who has the given role
13#
14# Notes:
15# * Call the method: robot.auth.hasRole(msg.envelope.user,'<role>')
16# * returns bool true or false
17#
18# * the 'admin' role can only be assigned through the environment variable
19# * roles are all transformed to lower case
20#
21# * The script assumes that user IDs will be unique on the service end as to
22# correctly identify a user. Names were insecure as a user could impersonate
23# a user
24
25config =
26 admin_list: process.env.HUBOT_AUTH_ADMIN
27
28module.exports = (robot) ->
29
30 unless config.admin_list?
31 robot.logger.warning 'The HUBOT_AUTH_ADMIN environment variable not set'
32
33 if config.admin_list?
34 admins = config.admin_list.split ','
35 else
36 admins = []
37
38 class Auth
39 isAdmin: (user) ->
40 user.id.toString() in admins
41
42 hasRole: (user, roles) ->
43 userRoles = @userRoles(user)
44 if userRoles?
45 roles = [roles] if typeof roles is 'string'
46 for role in roles
47 return true if role in userRoles
48 return false
49
50 usersWithRole: (role) ->
51 users = []
52 for own key, user of robot.brain.data.users
53 if @hasRole(user, role)
54 users.push(user.name)
55 users
56
57 userRoles: (user) ->
58 roles = []
59 if user? and robot.auth.isAdmin user
60 roles.push('admin')
61 if user.roles?
62 roles = roles.concat user.roles
63 roles
64
65 robot.auth = new Auth
66
67 robot.respond /@?(.+) ha(s|ve) (["'\w: -_]+) role/i, (msg) ->
68 unless robot.auth.isAdmin msg.message.user
69 msg.reply "Sorry, only admins can assign roles."
70 else
71 name = msg.match[1].trim()
72 if name.toLowerCase() is 'i' then name = msg.message.user.name
73 newRole = msg.match[3].trim().toLowerCase()
74
75 unless name.toLowerCase() in ['', 'who', 'what', 'where', 'when', 'why']
76 user = robot.brain.userForName(name)
77 return msg.reply "#{name} does not exist" unless user?
78 user.roles or= []
79
80 if newRole in user.roles
81 msg.reply "#{name} already has the '#{newRole}' role."
82 else
83 if newRole is 'admin'
84 msg.reply "Sorry, the 'admin' role can only be defined in the HUBOT_AUTH_ADMIN env variable."
85 else
86 myRoles = msg.message.user.roles or []
87 user.roles.push(newRole)
88 msg.reply "OK, #{name} has the '#{newRole}' role."
89
90 robot.respond /@?(.+) do(n't|esn't|es)( not)? have (["'\w: -_]+) role/i, (msg) ->
91 unless robot.auth.isAdmin msg.message.user
92 msg.reply "Sorry, only admins can remove roles."
93 else
94 name = msg.match[1].trim()
95 if name.toLowerCase() is 'i' then name = msg.message.user.name
96 newRole = msg.match[4].trim().toLowerCase()
97
98 unless name.toLowerCase() in ['', 'who', 'what', 'where', 'when', 'why']
99 user = robot.brain.userForName(name)
100 return msg.reply "#{name} does not exist" unless user?
101 user.roles or= []
102
103 if newRole is 'admin'
104 msg.reply "Sorry, the 'admin' role can only be removed from the HUBOT_AUTH_ADMIN env variable."
105 else
106 myRoles = msg.message.user.roles or []
107 user.roles = (role for role in user.roles when role isnt newRole)
108 msg.reply "OK, #{name} doesn't have the '#{newRole}' role."
109
110 robot.respond /what roles? do(es)? @?(.+) have\?*$/i, (msg) ->
111 name = msg.match[2].trim()
112 if name.toLowerCase() is 'i' then name = msg.message.user.name
113 user = robot.brain.userForName(name)
114 return msg.reply "#{name} does not exist" unless user?
115 userRoles = robot.auth.userRoles(user)
116
117 if userRoles.length == 0
118 msg.reply "#{name} has no roles."
119 else
120 msg.reply "#{name} has the following roles: #{userRoles.join(', ')}."
121
122 robot.respond /who has (["'\w: -_]+) role\?*$/i, (msg) ->
123 role = msg.match[1]
124 userNames = robot.auth.usersWithRole(role) if role?
125
126 if userNames.length > 0
127 msg.reply "The following people have the '#{role}' role: #{userNames.join(', ')}"
128 else
129 msg.reply "There are no people that have the '#{role}' role."