From 1db3733b380dbe2e47b8985a78cd5d8d529ece3f Mon Sep 17 00:00:00 2001 From: John Tordoff <> Date: Sun, 19 Nov 2023 08:42:24 -0500 Subject: [PATCH] make bitbucket configurable via api v2 --- addons/bitbucket/models.py | 43 ++++++++++++++++++++++- api/base/settings/defaults.py | 4 +-- api_tests/nodes/views/test_node_addons.py | 2 +- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/addons/bitbucket/models.py b/addons/bitbucket/models.py index b9f22b79ce2e..f3b49ee72660 100644 --- a/addons/bitbucket/models.py +++ b/addons/bitbucket/models.py @@ -15,8 +15,9 @@ from framework.auth import Auth from osf.models.external import ExternalProvider from osf.models.files import File, Folder, BaseFileNode +from rest_framework import exceptions as drf_exceptions from website import settings -from website.util import web_url_for +from website.util import web_url_for, api_v2_url hook_domain = bitbucket_settings.HOOK_DOMAIN or settings.DOMAIN @@ -454,3 +455,43 @@ def before_make_public(self, node): def after_delete(self, user): self.deauthorize(Auth(user=user), log=True) + + def get_folders(self, path, folder_id): + return [{ + 'id': repo['full_name'], + 'path': '/', + 'addon': 'bitbucket', + 'kind': 'folder', + 'name': repo['full_name'], + 'urls': { + 'folders': api_v2_url(f'nodes/{self.owner._id}/addons/bitbucket/folders/'), + } + } for repo in BitbucketClient(access_token=self.external_account.oauth_key).repos()] + + def set_folder(self, folder_id, auth): + connection = BitbucketClient(access_token=self.external_account.oauth_key) + username, repo = folder_id.split('/') + if not connection.repo(username, repo): + raise drf_exceptions.PermissionDenied(f'The credentials provided are incorrect.') + + user_settings = auth.user.get_or_add_addon('bitbucket') + user_settings.save() + self.user_settings = user_settings + self.save() + + if folder_id != self.repo: + self.repo = repo + self.user = username + self.owner.add_log( + action='bitbucket_repo_linked', + params={ + 'project': self.owner.parent_id, + 'node': self.owner._id, + 'bitbucket': { + 'user': self.external_account.display_name, + 'repo': folder_id + } + }, + auth=auth + ) + self.save() diff --git a/api/base/settings/defaults.py b/api/base/settings/defaults.py index 54fdc7672863..4114c2d0c34f 100644 --- a/api/base/settings/defaults.py +++ b/api/base/settings/defaults.py @@ -302,8 +302,8 @@ VARNISH_SERVERS = osf_settings.VARNISH_SERVERS ESI_MEDIA_TYPES = osf_settings.ESI_MEDIA_TYPES -ADDONS_FOLDER_CONFIGURABLE = ['box', 'dropbox', 's3', 'googledrive', 'figshare', 'owncloud', 'onedrive'] -ADDONS_OAUTH = ADDONS_FOLDER_CONFIGURABLE + ['dataverse', 'github', 'bitbucket', 'gitlab', 'mendeley', 'zotero', 'forward', 'boa'] +ADDONS_FOLDER_CONFIGURABLE = ['box', 'dropbox', 's3', 'googledrive', 'figshare', 'owncloud', 'onedrive', 'bitbucket'] +ADDONS_OAUTH = ADDONS_FOLDER_CONFIGURABLE + ['dataverse', 'github', 'gitlab', 'mendeley', 'zotero', 'forward', 'boa'] BYPASS_THROTTLE_TOKEN = 'test-token' diff --git a/api_tests/nodes/views/test_node_addons.py b/api_tests/nodes/views/test_node_addons.py index cebd3f322e77..377c49c3c971 100644 --- a/api_tests/nodes/views/test_node_addons.py +++ b/api_tests/nodes/views/test_node_addons.py @@ -680,7 +680,7 @@ class TestNodeWikiAddon(NodeUnmanageableAddonTestSuiteMixin, ApiAddonTestCase): # OAUTH -class TestNodeBitbucketAddon(NodeOAuthAddonTestSuiteMixin, ApiAddonTestCase): +class TestNodeBitbucketAddon(NodeConfigurableAddonTestSuiteMixin, ApiAddonTestCase): short_name = 'bitbucket' AccountFactory = BitbucketAccountFactory NodeSettingsFactory = BitbucketNodeSettingsFactory