diff options
| author | 2018-06-23 17:10:05 +0000 | |
|---|---|---|
| committer | 2018-06-23 17:10:05 +0000 | |
| commit | 9a50fe1a266c3a095563ed7abdf7fc9dd374d0bf (patch) | |
| tree | a6b796051cb7b7811ce8528b2b4501278422591e | |
| parent | Fix linting issue (diff) | |
Add some documentation to the team_edit_repo route
Diffstat (limited to '')
| -rw-r--r-- | pysite/views/main/jams/team_edit_repo.py | 36 | 
1 files changed, 28 insertions, 8 deletions
| diff --git a/pysite/views/main/jams/team_edit_repo.py b/pysite/views/main/jams/team_edit_repo.py index 719013ac..03f23f17 100644 --- a/pysite/views/main/jams/team_edit_repo.py +++ b/pysite/views/main/jams/team_edit_repo.py @@ -6,7 +6,7 @@ import requests  from flask import jsonify, request  from rethinkdb import ReqlNonExistenceError  from urllib3.util import parse_url -from werkzeug.exceptions import BadRequest, NotFound, Unauthorized +from werkzeug.exceptions import NotFound, Unauthorized  from pysite.base_route import APIView  from pysite.constants import ErrorCodes, GITLAB_ACCESS_TOKEN @@ -45,25 +45,29 @@ class JamsTeamEditRepo(APIView, DBMixin, OAuthMixin):              log.exception("Failed RethinkDB query")              raise NotFound() +        # Only team members can use this route          if not self.user_data["user_id"] in team["members"]:              raise Unauthorized()          repo_url = request.form.get("repo_url").strip() -        # check if repo is a valid GitLab repo URI +        # Check if repo is a valid GitLab repo URI          url = parse_url(repo_url)          if url.host != "gitlab.com" or url.path is None: -            raise BadRequest() +            return self.error( +                ErrorCodes.incorrect_parameters, +                "Not a GitLab repository." +            ) -        project_path = url.path.strip("/") +        project_path = url.path.strip("/")  # /user/repository/ --> user/repository          if len(project_path.split("/")) < 2:              return self.error(                  ErrorCodes.incorrect_parameters,                  "Not a valid repository."              ) -        word_regex = re.compile("^[\-\w]+$") +        word_regex = re.compile("^[\-\.\w]+$")  # Alphanumerical, underscores, periods, and dashes          for segment in project_path.split("/"):              if not word_regex.fullmatch(segment):                  return self.error( @@ -71,11 +75,15 @@ class JamsTeamEditRepo(APIView, DBMixin, OAuthMixin):                      "Not a valid repository."                  ) -        project_path_encoded = quote(project_path, safe='') +        project_path_encoded = quote(project_path, safe='')  # Replaces / with %2F, etc. + +        # If validation returns something else than True, abort          validation = self.validate_project(team, project_path_encoded)          if validation is not True:              return validation +        # Update the team repo +        # Note: the team repo is only stored using its path (e.g. user/repository)          team_obj = self.db.get(self.table_name, team_id)          team_obj["repo"] = project_path          self.db.insert(self.table_name, team_obj, conflict="update") @@ -87,7 +95,9 @@ class JamsTeamEditRepo(APIView, DBMixin, OAuthMixin):          )      def validate_project(self, team, project_path): -        # check on GitLab if the project exists, and is a fork +        # Check on GitLab if the project exists +        # NB: certain fields (such as "forked_from_project") need an access token +        # to be visible. Set the GITLAB_ACCESS_TOKEN env variable to solve this          query_response = self.request_project(project_path)          if query_response.status_code != 200: @@ -96,10 +106,13 @@ class JamsTeamEditRepo(APIView, DBMixin, OAuthMixin):                  "Not a valid repository."              ) +        # Check if the jam's base repo has been set by staff +        # If not, just ignore the fork check and proceed          if "repo" not in team["jam"]:              return True          jam_repo = team["jam"]["repo"] +        # Check if the provided repo is a forked repo          project_data = query_response.json()          if "forked_from_project" not in project_data:              return self.error( @@ -107,15 +120,20 @@ class JamsTeamEditRepo(APIView, DBMixin, OAuthMixin):                  "This repository is not a fork of the jam's repository."              ) -        # check if it's a fork for the right repo +        # Check if the provided repo is forking the base repo          forked_from_project = project_data["forked_from_project"] +        # The jam repo is stored in full (e.g. https://gitlab.com/user/repository)          jam_repo_path = quote(parse_url(jam_repo).path.strip("/"), safe='') + +        # Get info about the code jam repo          jam_repo_response = self.request_project(jam_repo_path) +        # Something went wrong, fail silently          if jam_repo_response.status_code != 200:              return True +        # Check if the IDs for the code jam repo and the fork source match          jam_repo_data = jam_repo_response.json()          if jam_repo_data["id"] != forked_from_project["id"]:              return self.error( @@ -123,9 +141,11 @@ class JamsTeamEditRepo(APIView, DBMixin, OAuthMixin):                  "This repository is not a fork of the jam's repository."              ) +        # All good          return True      def request_project(self, project_path): +        # Request the project details using a private access token          return requests.get(              self.gitlab_projects_api_endpoint.format(project_path),              params={ | 
