Skip to content

Commit

Permalink
feat: add optional google drive permissions sync
Browse files Browse the repository at this point in the history
  • Loading branch information
bobheadxi committed Sep 24, 2020
1 parent a99f9d5 commit ccee0bd
Show file tree
Hide file tree
Showing 13 changed files with 416 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ cryptography = "*"
requests = "*"
apscheduler = "*"
watchtower = "==0.7.3"
google-api-python-client = "*"
google-auth-oauthlib = "*"

[dev-packages]
awscli = "*"
Expand Down
171 changes: 166 additions & 5 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 50 additions & 4 deletions app/controller/command/commands/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from db.utils import get_team_by_name
from interface.github import GithubAPIException, GithubInterface
from interface.slack import SlackAPIError
from interface.gcp import GCPInterface
from config import Config
from app.model import Team, User
from utils.slack_parse import check_permissions
from typing import Any, List
from typing import Any, List, Optional


class TeamCommand(Command):
Expand All @@ -27,19 +28,22 @@ def __init__(self,
config: Config,
db_facade: DBFacade,
gh: GithubInterface,
sc: Any):
sc: Any,
gcp: Optional[GCPInterface] = None):
"""
Initialize team command parser.
:param db_facade: Given Dynamo_DB Facade
:param gh: Given Github Interface
:param sc: Given Slack Client Interface
"param gcp: Given GCP client
"""
logging.info("Initializing TeamCommand instance")
self.facade = db_facade
self.gh = gh
self.config = config
self.sc = sc
self.gcp = gcp
self.desc = "for dealing with teams"
self.parser = ArgumentParser(prog="/rocket")
self.parser.add_argument("team")
Expand Down Expand Up @@ -93,6 +97,8 @@ def init_subparsers(self) -> _SubParsersAction:
parser_create.add_argument("--lead", type=str, action='store',
help="Add given user as team lead"
"to created team.")
parser_create.add_argument("--folder", type=str, action='store',
help="Drive folder ID for this team.")

"""Parser for add command."""
parser_add = subparsers.add_parser("add")
Expand Down Expand Up @@ -128,6 +134,8 @@ def init_subparsers(self) -> _SubParsersAction:
help="Display name the team should have.")
parser_edit.add_argument("--platform", type=str, action='store',
help="Platform the team should have.")
parser_edit.add_argument("--folder", type=str, action='store',
help="Drive folder ID for this team.")

"""Parser for lead command."""
parser_lead = subparsers.add_parser("lead")
Expand Down Expand Up @@ -202,7 +210,8 @@ def handle(self,
"name": args.name,
"platform": args.platform,
"channel": args.channel,
"lead": args.lead
"lead": args.lead,
"folder": args.folder,
}
return self.create_helper(param_list, user_id)

Expand All @@ -224,7 +233,8 @@ def handle(self,
param_list = {
"team_name": args.team_name,
"name": args.name,
"platform": args.platform
"platform": args.platform,
"folder": args.folder,
}
return self.edit_helper(param_list, user_id)

Expand Down Expand Up @@ -318,6 +328,9 @@ def create_helper(self, param_list, user_id) -> ResponseTuple:
if param_list["platform"] is not None:
msg += f"platform: {param_list['platform']}, "
team.platform = param_list['platform']
if param_list["folder"] is not None:
msg += f"folder: {param_list['folder']}"
team.folder = param_list['folder']
if param_list["channel"] is not None:
msg += "added channel, "
for member_id in self.sc.get_channel_users(
Expand Down Expand Up @@ -467,6 +480,9 @@ def edit_helper(self, param_list, user_id) -> ResponseTuple:
if param_list['platform'] is not None:
msg += f"platform: {param_list['platform']}"
team.platform = param_list['platform']
if param_list['folder'] is not None:
msg += f"folder: {param_list['folder']}"
team.folder = param_list['folder']
self.facade.store(team)
ret = {'attachments': [team.get_attachment()], 'text': msg}
return ret, 200
Expand Down Expand Up @@ -605,6 +621,9 @@ def refresh_helper(self, user_id) -> ResponseTuple:

# add all members (if not already added) to the 'all' team
self.refresh_all_team()

# enforce Drive permissions
self.refresh_drive_permissions()
except GithubAPIException as e:
logging.error("team refresh unsuccessful due to github error")
return "Refresh teams was unsuccessful with " \
Expand Down Expand Up @@ -650,3 +669,30 @@ def refresh_all_team(self):
self.facade.store(team_all)
else:
logging.error(f'Could not create {all_name}. Aborting.')

def refresh_drive_permissions(self):
"""
Refresh Google Drive permissions based on user role. If no GCP client
is provided, this function is a no-op.
"""

if self.gcp is None:
logging.debug("GCP not enabled, skipping drive permissions")
return

all_teams: List[Team] = self.facade.query(Team)
for t in all_teams:
if len(t.folder) == 0:
continue

emails: List[str] = []
for m in t.members:
if len(m.email) > 0:
emails.append(m.email)

if len(emails) > 0:
logging.info("Synchronizing permissions for "
+ f"{t.github_team_name}'s folder ({t.folder}) "
+ f"to {emails}")
self.gcp.set_drive_permissions(
t.folder, t.github_team_name, emails)
Loading

0 comments on commit ccee0bd

Please sign in to comment.