Skip to content

Commit

Permalink
feat: add ability to set permissions from teams
Browse files Browse the repository at this point in the history
  • Loading branch information
bobheadxi committed Sep 28, 2020
1 parent 96ec12c commit edd1bbc
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
34 changes: 30 additions & 4 deletions app/controller/command/commands/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from argparse import ArgumentParser, _SubParsersAction
from app.controller import ResponseTuple
from app.controller.command.commands.base import Command
from app.model.permissions import Permissions
from db.facade import DBFacade
from db.utils import get_team_by_name
from interface.github import GithubAPIException, GithubInterface
Expand Down Expand Up @@ -385,8 +386,9 @@ def add_helper(self, param_list, user_id) -> ResponseTuple:
"""
try:
command_user = self.facade.retrieve(User, user_id)
command_team = param_list['team_name']
teams = self.facade.query(Team, [('github_team_name',
param_list['team_name'])])
command_team)])
if len(teams) != 1:
return self.lookup_error, 200
team = teams[0]
Expand All @@ -397,7 +399,20 @@ def add_helper(self, param_list, user_id) -> ResponseTuple:
team.add_member(user.github_id)
self.gh.add_team_member(user.github_username, team.github_team_id)
self.facade.store(team)
msg = "Added User to " + param_list['team_name']

# If this team is a team with special permissions, promote the user
promoted_level = Permissions.member
if command_team == self.config.github_team_admin:
promoted_level = Permissions.admin
elif command_team == self.config.github_team_leads:
promoted_level = Permissions.team_lead

msg = "Added User to " + command_team
if promoted_level != Permissions.member:
logging.info(f"Promoting {command_user} to {promoted_level}")
user.permissions_level = promoted_level
self.facade.store(user)
msg += f" and promoted user to {promoted_level}"
ret = {'attachments': [team.get_attachment()], 'text': msg}
return ret, 200

Expand All @@ -424,8 +439,9 @@ def remove_helper(self, param_list, user_id) -> ResponseTuple:
"""
try:
command_user = self.facade.retrieve(User, user_id)
command_team = param_list['team_name']
teams = self.facade.query(Team, [('github_team_name',
param_list['team_name'])])
command_team)])
if len(teams) != 1:
return self.lookup_error, 200
team = teams[0]
Expand All @@ -442,7 +458,17 @@ def remove_helper(self, param_list, user_id) -> ResponseTuple:
self.gh.remove_team_member(user.github_username,
team.github_team_id)
self.facade.store(team)
msg = "Removed User from " + param_list['team_name']

msg = "Removed User from " + command_team

# If this team is a team with special permissions, demote the user
if command_team == self.config.github_team_admin\
or command_team == self.config.github_team_leads:
logging.info(f"Demoting {command_user} to member")
user.permissions_level = Permissions.member
self.facade.store(user)
msg += " and demoted user"

ret = {'attachments': [team.get_attachment()], 'text': msg}
return ret, 200

Expand Down
6 changes: 6 additions & 0 deletions config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Config:
'GITHUB_APP_ID': 'github_app_id',
'GITHUB_ORG_NAME': 'github_org_name',
'GITHUB_DEFAULT_TEAM_NAME': 'github_team_all',
'GITHUB_ADMIN_TEAM_NAME': 'github_team_admin',
'GITHUB_LEADS_TEAM_NAME': 'github_team_leads',
'GITHUB_WEBHOOK_ENDPT': 'github_webhook_endpt',
'GITHUB_WEBHOOK_SECRET': 'github_webhook_secret',
'GITHUB_KEY': 'github_key',
Expand All @@ -39,6 +41,8 @@ class Config:
OPTIONALS = {
'AWS_LOCAL': 'False',
'GITHUB_DEFAULT_TEAM_NAME': 'all',
'GITHUB_ADMIN_TEAM_NAME': '',
'GITHUB_LEADS_TEAM_NAME': '',
'GCP_SERVICE_ACCOUNT_CREDENTIALS': '',
'GCP_SERVICE_ACCOUNT_SUBJECT': '',
}
Expand Down Expand Up @@ -84,6 +88,8 @@ def _set_attrs(self):
self.github_app_id = ''
self.github_org_name = ''
self.github_team_all = ''
self.github_team_admin = ''
self.github_team_leads = ''
self.github_webhook_endpt = ''
self.github_webhook_secret = ''
self.github_key = ''
Expand Down
23 changes: 23 additions & 0 deletions docs/Config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ GITHUB_ORG_NAME
The name of your Github organization (the string in the URL whenever you
go to the organization.

GITHUB_DEFAULT_TEAM_NAME
------------------------

The name of the GitHub team in your organization that all users should
be added to. Optional, defaults to ``all``.

GITHUB_ADMIN_TEAM_NAME
----------------------

The name of the GitHub team in your organization that should be automatically
promoted to Rocket administrators. Optional.

Note that this does not mean all Rocket administrators will be added to this
team.

GITHUB_LEADS_TEAM_NAME
----------------------

The name of the GitHub team in your organization that should be automatically
promoted to Rocket team leads. Optional.

Note that this does not mean all Rocket team leads will be added to this team.

GITHUB_WEBHOOK_ENDPT
--------------------

Expand Down
3 changes: 3 additions & 0 deletions sample-env
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ SLACK_API_TOKEN=''

GITHUB_APP_ID=''
GITHUB_ORG_NAME='ubclaunchpad'
GITHUB_DEFAULT_TEAM_NAME='all'
GITHUB_ADMIN_TEAM_NAME='exec'
GITHUB_LEADS_TEAM_NAME='leads'
GITHUB_WEBHOOK_ENDPT='/webhook'
GITHUB_WEBHOOK_SECRET=''
GITHUB_KEY='BEGIN KEY END KEY'
Expand Down
42 changes: 40 additions & 2 deletions tests/app/controller/command/commands/team_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ def setUp(self):
self.admin = create_test_admin('Uadmin')
self.t0 = Team("BRS", "brs", "web")
self.t1 = Team("OTEAM", "other team", "android")
self.t2 = Team("LEADS", "leads", "")
self.db = MemoryDB(
users=[self.u0, self.u1, self.admin],
teams=[self.t0, self.t1])
teams=[self.t0, self.t1, self.t2])

self.sc = mock.MagicMock()
self.testcommand = TeamCommand(self.config, self.db, self.gh, self.sc)
self.help_text = self.testcommand.help
self.maxDiff = None

self.config.github_team_all = 'all'
self.config.github_team_leads = 'leads'

def test_get_help(self):
subcommands = list(self.testcommand.subparser.choices.keys())
Expand Down Expand Up @@ -70,7 +72,8 @@ def test_handle_subcommand_help(self):
def test_handle_list(self):
attachment = [
self.t0.get_basic_attachment(),
self.t1.get_basic_attachment()
self.t1.get_basic_attachment(),
self.t2.get_basic_attachment(),
]
with self.app.app_context():
resp, code = self.testcommand.handle('team list', self.u0.slack_id)
Expand Down Expand Up @@ -237,6 +240,23 @@ def test_handle_add_lookup_error(self):
(self.testcommand.lookup_error, 200))
self.gh.add_team_member.assert_not_called()

def test_handle_add_promote(self):
self.u0.github_username = 'myuser'
self.u0.github_id = 'otherID'
self.t2.github_team_id = 'githubid'
with self.app.app_context():
resp, code = self.testcommand.handle(
f'team add leads {self.u0.slack_id}',
self.admin.slack_id)
expect_msg = 'Added User to leads and promoted user to team_lead'
expect = {'attachments': [self.t2.get_attachment()],
'text': expect_msg}
self.assertDictEqual(resp, expect)
self.assertEqual(code, 200)
self.assertTrue(self.t2.has_member("otherID"))
self.assertEquals(self.u0.permissions_level, Permissions.team_lead)
self.gh.add_team_member.assert_called_once_with('myuser', 'githubid')

def test_handle_remove(self):
self.u0.github_id = 'githubID'
self.u0.github_username = 'myuser'
Expand Down Expand Up @@ -268,6 +288,24 @@ def test_handle_remove_user_not_in_team(self):
self.t0.github_team_id)
self.gh.remove_team_member.assert_not_called()

def test_handle_remove_demote(self):
self.u0.github_username = 'myuser'
self.u0.github_id = 'otherID'
self.t2.add_member(self.u0.github_id)
with self.app.app_context():
resp, code = self.testcommand.handle(
f'team remove leads {self.u0.slack_id}',
self.admin.slack_id)
expect_msg = 'Removed User from leads and demoted user'
expect = {'attachments': [self.t2.get_attachment()],
'text': expect_msg}
self.assertDictEqual(resp, expect)
self.assertEqual(code, 200)
self.assertEquals(self.u0.permissions_level, Permissions.member)
self.gh.remove_team_member.assert_called_once_with(
self.u0.github_username,
self.t2.github_team_id)

def test_handle_remove_not_admin(self):
with self.app.app_context():
self.assertTupleEqual(self.testcommand.handle(
Expand Down

0 comments on commit edd1bbc

Please sign in to comment.