diff --git a/CHANGES.md b/CHANGES.md index 545a01c..f8de79d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,13 +1,18 @@ # Changelog ## 2.2.0 - +* Add new ``github.add_repository_collaborator`` action which allows user to add a collaborator to repository. +* Add new ``github.check_user_repository_collaborator`` action which allows user to check if an user is a collaborator's repository. +* Add new ``github.get_repository_collaborators`` action which allows user to list the collaborators of repository. +* Add new ``github.add_update_repository_team`` action which allows user to add a team to repository. +* Add new ``github.check_team_permissions_for_repository`` action which allows user to check if a team has access to repository. * Add new ``github.create_organization_repository`` action which allows user to create an organization repository. * Add new ``github.create_repository_authenticated_user`` action which allows user to create an user repository. * Add new ``github.create_repository_from_template`` action which allows user to create a repository from template. * Bug fix on ``github.store_oauth_token.`` to api save the token correctly so that it can be read later. * Segure improvement on ``github.store_oauth_token.`` to encrypt de github token in web interface. + ## 2.1.1 * Bug fix (#43) where the sensor will throw an exception if no events are returned from the GitHub api. diff --git a/actions/add_repository_collaborator.py b/actions/add_repository_collaborator.py new file mode 100644 index 0000000..e5174ad --- /dev/null +++ b/actions/add_repository_collaborator.py @@ -0,0 +1,29 @@ +import time +import datetime + + +from lib.base import BaseGithubAction + +__all__ = [ + 'AddRepositoryCollaboratorAction' +] + +class AddRepositoryCollaboratorAction(BaseGithubAction): + def run(self, api_user, owner, repo, username, github_type, permission ): + + enterprise = self._is_enterprise(github_type) + + if api_user: + self.token = self._get_user_token(api_user, enterprise) + + payload = { "permission": permission } + + response = self._request("PUT", + "/repos/{}/{}/collaborators/{}".format(owner,repo,username ), + payload, + self.token, + enterprise) + + results = {'response': response} + + return results diff --git a/actions/add_repository_collaborator.yaml b/actions/add_repository_collaborator.yaml new file mode 100644 index 0000000..76b6808 --- /dev/null +++ b/actions/add_repository_collaborator.yaml @@ -0,0 +1,44 @@ +--- +name: add_repository_collaborator +runner_type: python-script +pack: github +description: > + Add a repository collaborator. + Example: + st2 run github.add_repository_collaborator owner="organization" repo="reponame" username="collaborator" api_user="token_name" +enabled: true +entry_point: add_repository_collaborator.py +parameters: + api_user: + type: "string" + description: "The API user" + default: "{{action_context.api_user|default(None)}}" + owner: + type: "string" + description: "The account owner of the repository. The name is not case sensitive.." + required: true + repo: + type: "string" + description: "The name of the repository. The name is not case sensitive." + required: true + username: + type: "string" + description: "The handle for the GitHub user account." + required: true + github_type: + type: "string" + description: "The type of github installation to target, if unset will use the configured default." + enum: + - "online" + - "enterprise" + default: "enterprise" + permission: + type: "string" + description: "The permission to grant the collaborator. Only valid on organization-owned repositories. In addition to the enumerated values, you can also specify a custom repository role name, if the owning organization has defined any." + enum: + - "pull" + - "push" + - "admin" + - "maintain" + - "triage" + default: "push" \ No newline at end of file diff --git a/actions/add_update_repository_team.py b/actions/add_update_repository_team.py new file mode 100644 index 0000000..93f8e14 --- /dev/null +++ b/actions/add_update_repository_team.py @@ -0,0 +1,29 @@ +import time +import datetime + + +from lib.base import BaseGithubAction + +__all__ = [ + 'AddUpdateRepositoryTeamAction' +] + +class AddUpdateRepositoryTeamAction(BaseGithubAction): + def run(self, api_user, org, team_slug, owner, repo, github_type, permission ): + + enterprise = self._is_enterprise(github_type) + + if api_user: + self.token = self._get_user_token(api_user, enterprise) + + payload = { "permission": permission } + + response = self._request("PUT", + "/orgs/{}/teams/{}/repos/{}/{}".format(org,team_slug,owner,repo ), + payload, + self.token, + enterprise) + + results = {'response': response} + + return results diff --git a/actions/add_update_repository_team.yaml b/actions/add_update_repository_team.yaml new file mode 100644 index 0000000..fd5fef0 --- /dev/null +++ b/actions/add_update_repository_team.yaml @@ -0,0 +1,48 @@ +--- +name: add_update_repository_team +runner_type: python-script +pack: github +description: > + Add or update repository team. + Example: + st2 run github.add_update_repository_team organization="organization" owner="owner" repo="reponame" team_slug="team_id" api_user="token_name" +enabled: true +entry_point: add_update_repository_team.py +parameters: + api_user: + type: "string" + description: "The API user" + default: "{{action_context.api_user|default(None)}}" + org: + type: "string" + description: "The organization name. The name is not case sensitive." + required: true + team_slug: + type: "string" + description: "The slug of the team name." + required: true + owner: + type: "string" + description: "The account owner of the repository. The name is not case sensitive." + required: true + repo: + type: "string" + description: "The name of the repository. The name is not case sensitive." + required: true + github_type: + type: "string" + description: "The type of github installation to target, if unset will use the configured default." + enum: + - "online" + - "enterprise" + default: "enterprise" + permission: + type: "string" + description: "The permission to grant the team on this repository. In addition to the enumerated values, you can also specify a custom repository role name, if the owning organization has defined any. If no permission is specified, the team's permission attribute will be used to determine what permission to grant the team on this repository." + enum: + - "pull" + - "push" + - "admin" + - "maintain" + - "triage" + default: "push" \ No newline at end of file diff --git a/actions/check_team_permissions_for_repository.py b/actions/check_team_permissions_for_repository.py new file mode 100644 index 0000000..81fd33f --- /dev/null +++ b/actions/check_team_permissions_for_repository.py @@ -0,0 +1,37 @@ +import time +import datetime + + +from lib.base import BaseGithubAction + +__all__ = [ + 'CheckTeamPermissionsForRepository' +] + +class CheckTeamPermissionsForRepository(BaseGithubAction): + def run(self, api_user, org, team_slug, owner, repo, github_type ): + + enterprise = self._is_enterprise(github_type) + + if api_user: + self.token = self._get_user_token(api_user, enterprise) + + try: + response = self._request("GET", + "/orgs/{}/teams/{}/repos/{}/{}".format(org,team_slug,owner,repo ), + {}, + self.token, + enterprise) + + results = {'response': "The team {} has access to the repository {}".format(team_slug, repo)} + except OSError as err: + raise err + except ValueError as err: + raise err + except Exception as err: + if str(err).find("404"): + results = {'response': "The team don't have access to the repository or not found"} + else: + raise err + + return results diff --git a/actions/check_team_permissions_for_repository.yaml b/actions/check_team_permissions_for_repository.yaml new file mode 100644 index 0000000..7802865 --- /dev/null +++ b/actions/check_team_permissions_for_repository.yaml @@ -0,0 +1,38 @@ +--- +name: check_team_permissions_for_repository +runner_type: python-script +pack: github +description: > + Check team permissions for a repository. + Example: + st2 run github.check_team_permissions_for_repository organization="organization" owner="owner" repo="reponame" team_slug="team_id" api_user="token_name" +enabled: true +entry_point: check_team_permissions_for_repository.py +parameters: + api_user: + type: "string" + description: "The API user" + default: "{{action_context.api_user|default(None)}}" + org: + type: "string" + description: "The organization name. The name is not case sensitive." + required: true + team_slug: + type: "string" + description: "The slug of the team name." + required: true + owner: + type: "string" + description: "The account owner of the repository. The name is not case sensitive." + required: true + repo: + type: "string" + description: "The name of the repository. The name is not case sensitive." + required: true + github_type: + type: "string" + description: "The type of github installation to target, if unset will use the configured default." + enum: + - "online" + - "enterprise" + default: "enterprise" \ No newline at end of file diff --git a/actions/check_user_repository_collaborator.py b/actions/check_user_repository_collaborator.py new file mode 100644 index 0000000..1cea121 --- /dev/null +++ b/actions/check_user_repository_collaborator.py @@ -0,0 +1,36 @@ +import time +import datetime +import json + +from lib.base import BaseGithubAction + +__all__ = [ + 'CheckIfUserIsRepositoryCollaborator' +] + +class CheckIfUserIsRepositoryCollaborator(BaseGithubAction): + def run(self, api_user, owner, repo, username, github_type ): + + enterprise = self._is_enterprise(github_type) + + if api_user: + self.token = self._get_user_token(api_user, enterprise) + + try: + response = self._request("GET", + "/repos/{}/{}/collaborators/{}".format(owner,repo,username ), + {}, + self.token, + enterprise) + results = {'response': "The user {} is a Collaborator".format(username)} + except OSError as err: + raise err + except ValueError as err: + raise err + except Exception as err: + if str(err).find("404"): + results = {'response': "is not a Collaborator or not found"} + else: + raise err + + return results diff --git a/actions/check_user_repository_collaborator.yaml b/actions/check_user_repository_collaborator.yaml new file mode 100644 index 0000000..7d14c81 --- /dev/null +++ b/actions/check_user_repository_collaborator.yaml @@ -0,0 +1,34 @@ +--- +name: check_user_repository_collaborator +runner_type: python-script +pack: github +description: > + Check if a user is a repository collaborator. + Example: + st2 run github.check_user_repository_collaborator owner="organization" repo="reponame" username="collaborator" api_user="token_name" +enabled: true +entry_point: check_user_repository_collaborator.py +parameters: + api_user: + type: "string" + description: "The API user" + default: "{{action_context.api_user|default(None)}}" + owner: + type: "string" + description: "The account owner of the repository. The name is not case sensitive." + required: true + repo: + type: "string" + description: "The name of the repository. The name is not case sensitive." + required: true + username: + type: "string" + description: "The handle for the GitHub user account." + required: true + github_type: + type: "string" + description: "The type of github installation to target, if unset will use the configured default." + enum: + - "online" + - "enterprise" + default: "enterprise" \ No newline at end of file diff --git a/actions/get_repository_collaborators.py b/actions/get_repository_collaborators.py new file mode 100644 index 0000000..65988d7 --- /dev/null +++ b/actions/get_repository_collaborators.py @@ -0,0 +1,31 @@ +import time +import datetime + + +from lib.base import BaseGithubAction + +__all__ = [ + 'GetRepositoryCollaborators' +] + +class GetRepositoryCollaborators(BaseGithubAction): + def run(self, api_user, owner, repo, affiliation, per_page, page, github_type ): + + enterprise = self._is_enterprise(github_type) + + if api_user: + self.token = self._get_user_token(api_user, enterprise) + + payload = { "affiliation": affiliation, + "per_page": per_page, + "page": page } + + response = self._request("GET", + "/repos/{}/{}/collaborators".format(owner,repo), + payload, + self.token, + enterprise) + + results = {'response': response} + + return results diff --git a/actions/get_repository_collaborators.yaml b/actions/get_repository_collaborators.yaml new file mode 100644 index 0000000..455b9a3 --- /dev/null +++ b/actions/get_repository_collaborators.yaml @@ -0,0 +1,46 @@ +--- +name: get_repository_collaborators +runner_type: python-script +pack: github +description: > + List repository collaborators. + Example: + st2 run github.get_repository_collaborators owner="organization" repo="reponame" api_user="token_name" +enabled: true +entry_point: get_repository_collaborators.py +parameters: + api_user: + type: "string" + description: "The API user" + default: "{{action_context.api_user|default(None)}}" + owner: + type: "string" + description: "The account owner of the repository. The name is not case sensitive." + required: true + repo: + type: "string" + description: "The name of the repository. The name is not case sensitive." + required: true + affiliation: + type: "string" + description: "Filter collaborators returned by their affiliation. outside means all outside collaborators of an organization-owned repository. direct means all collaborators with permissions to an organization-owned repository, regardless of organization membership status. all means all collaborators the authenticated user can see." + enum: + - "outside" + - "direct" + - "all" + default: "all" + per_page: + type: "integer" + description: "The number of results per page (max 100)." + default: 30 + page: + type: "integer" + description: "Page number of the results to fetch." + default: 1 + github_type: + type: "string" + description: "The type of github installation to target, if unset will use the configured default." + enum: + - "online" + - "enterprise" + default: "enterprise" \ No newline at end of file