def verify_settings( user: str, org_name: str, base_url: str, token: str, template_org_name: Optional[str] = None, ) -> None: """See :py:meth:`repobee_plug.PlatformAPI.verify_settings`.""" plug.echo("Verifying settings ...") plug.echo("Testing Internet connection") if not http.is_internet_connection_available(): raise plug.InternetConnectionUnavailable() if not token: raise plug.BadCredentials( msg="token is empty. Check that REPOBEE_TOKEN environment " "variable is properly set, or supply the `--token` option.") g = github.Github(login_or_token=token, base_url=base_url) plug.echo("Trying to fetch user information ...") user_not_found_msg = ( f"user {user} could not be found. Possible reasons: " "bad base url, bad username or bad access token permissions") with _convert_404_to_not_found_error(user_not_found_msg): user_ = g.get_user(user) msg = (f"Specified login is {user}, " f"but the fetched user's login is {user_.login}.") if user_.login is None: msg = ("{msg} Possible reasons: bad api url that points to a " "GitHub instance, but not to the api endpoint.") raise plug.UnexpectedException(msg=msg) elif user_.login != user: msg = ( f"{msg} Possible reasons: unknown, rerun with -tb and open an " "issue on GitHub.") raise plug.UnexpectedException(msg=msg) plug.echo( f"SUCCESS: found user {user}, user exists and base url looks okay") plug.echo("Verifying access token scopes ...") scopes = g.oauth_scopes assert scopes is not None if not REQUIRED_TOKEN_SCOPES.issubset(scopes): raise plug.BadCredentials( "missing one or more access token scopes. " f"Actual: {scopes}. Required {REQUIRED_TOKEN_SCOPES}") plug.echo("SUCCESS: access token scopes look okay") GitHubAPI._verify_org(org_name, user, g) if template_org_name: GitHubAPI._verify_org(template_org_name, user, g) plug.echo("GREAT SUCCESS: all settings check out!")
def _try_api_request(ignore_statuses: Optional[Iterable[int]] = None): """Context manager for trying API requests. Args: ignore_statuses: One or more status codes to ignore (only applicable if the exception is a gitlab.exceptions.GitlabError). """ try: yield except gitlab.exceptions.GitlabError as e: if ignore_statuses and e.response_code in ignore_statuses: return if e.response_code == 404: raise plug.NotFoundError(str(e), status=404) from e elif e.response_code == 401: raise plug.BadCredentials( "credentials rejected, verify that token has correct access.", status=401, ) from e else: raise plug.PlatformError(str(e), status=e.response_code) from e except (exception.RepoBeeException, plug.PlugError): raise except Exception as e: raise plug.UnexpectedException( f"a {type(e).__name__} occured unexpectedly: {str(e)}") from e
def _verify_user(self) -> None: endpoint = "/user" response = self._request(requests.get, endpoint, error_msg="bad token") if response.json()["login"] != self._user: raise plug.BadCredentials( f"token does not belong to user '{self._user}'") plug.echo("Token and user OK")
def _verify_org(org_name: str, user: str, g: github.MainClass.Github): """Check that the organization exists and that the user is an owner.""" plug.echo("Trying to fetch organization {} ...".format(org_name)) org_not_found_msg = ( "organization {} could not be found. Possible " "reasons: org does not exist, user does not have " "sufficient access to organization." ).format(org_name) with _convert_404_to_not_found_error(org_not_found_msg): org = g.get_organization(org_name) plug.echo("SUCCESS: found organization {}".format(org_name)) plug.echo( "Verifying that user {} is an owner of organization {}".format( user, org_name ) ) if user not in (m.login for m in org.get_members(role="admin")): plug.log.warning( f"{user} is not an owner of {org_name}. " "Some features may not be available." ) if user not in (m.login for m in org.get_members()): raise plug.BadCredentials( f"user {user} is not a member of {org_name}" ) else: plug.echo( "SUCCESS: user {} is an owner of organization {}".format( user, org_name ) )
def _verify_membership(user: str, group): members = group.members.list(all=True) owners = { m.username for m in members if m.access_level == gitlab.const.OWNER_ACCESS } if user not in owners: plug.log.warning( f"{user} is not an owner of {group.name}. " "Some features may not be available." ) non_owners = { m.username for m in members if m.access_level != gitlab.const.OWNER_ACCESS } if user not in non_owners: raise plug.BadCredentials( f"user {user} is not a member of {group.name}" ) else: plug.echo( f"SUCCESS: User {user} is an owner of group {group.name}" )
def verify_settings( user: str, org_name: str, base_url: str, token: str, template_org_name: Optional[str] = None, ): """See :py:meth:`repobee_plug.PlatformAPI.verify_settings`.""" plug.echo("GitLabAPI is verifying settings ...") plug.echo("Testing Internet connection") if not http.is_internet_connection_available(): raise plug.InternetConnectionUnavailable() if not token: raise plug.BadCredentials( msg="Token is empty. Check that REPOBEE_TOKEN environment " "variable is properly set, or supply the `--token` option." ) gl = gitlab.Gitlab( base_url, private_token=token, ssl_verify=GitLabAPI._ssl_verify() ) plug.echo(f"Authenticating connection to {base_url}...") with _convert_error( gitlab.exceptions.GitlabAuthenticationError, plug.BadCredentials, "Could not authenticate token", ), _convert_error( requests.exceptions.ConnectionError, plug.PlatformError, f"Could not connect to {base_url}, please check the URL", ): gl.auth() authenticated_username = gl.user.username # type: ignore plug.echo( f"SUCCESS: Authenticated as {authenticated_username} at {base_url}" ) GitLabAPI._verify_group(org_name, gl) if template_org_name: GitLabAPI._verify_group(template_org_name, gl) plug.echo("GREAT SUCCESS: All settings check out!")
def _try_api_request(ignore_statuses: Optional[Iterable[int]] = None): """Context manager for trying API requests. Args: ignore_statuses: One or more status codes to ignore (only applicable if the exception is a github.GithubException). Raises: plug.NotFoundError plug.BadCredentials plug.PlatformError plug.ServiceNotFoundError plug.UnexpectedException """ try: yield except plug.PlugError: raise except github.GithubException as e: if ignore_statuses and e.status in ignore_statuses: return if e.status == 404: raise plug.NotFoundError(str(e), status=404) elif e.status == 401: raise plug.BadCredentials( "credentials rejected, verify that token has correct access.", status=401, ) else: raise plug.PlatformError(str(e), status=e.status) except gaierror: raise plug.ServiceNotFoundError( "GitHub service could not be found, check the url" ) except Exception as e: raise plug.UnexpectedException( "a {} occured unexpectedly: {}".format(type(e).__name__, str(e)) )