class GitLab(PlatformOAuth2): # Platform attributes name = 'gitlab' display_name = 'GitLab' account_url = 'https://gitlab.com/u/{user_name}' # Auth attributes # GitLab uses https://github.com/doorkeeper-gem/doorkeeper auth_url = 'https://gitlab.com/oauth/authorize' access_token_url = 'https://gitlab.com/oauth/token' # API attributes # http://doc.gitlab.com/ce/api/ api_format = 'json' api_paginator = header_links_paginator() api_url = 'https://gitlab.com/api/v3' # api_user_info_path = '/users/{user_id}' # api_user_name_info_path = '/users?username={user_name}' api_user_self_info_path = '/user' # api_team_members_path = '/groups/{user_name}/members' # The commented out paths are because we need this: # https://gitlab.com/gitlab-org/gitlab-ce/issues/13795 # User info extractors x_user_id = key('id') x_user_name = key('username') x_display_name = key('name') x_email = key('email') x_avatar_url = key('avatar_url')
class Autour(PlatformOAuth2): # Platform attributes name = 'autour' display_name = 'Autour.com' account_url = 'https://autour.com/{user_name}' allows_team_connect = True # Auth attributes auth_url = 'https://api.autour.com/oauth2' access_token_url = 'https://api.autour.com/oauth2/access_token' oauth_email_scope = 'user:email' oauth_default_scope = ['read:org'] # API attributes api_format = 'json' api_paginator = header_links_paginator() api_url = 'https://api.autour.com' api_app_auth_params = 'client_id={api_key}&client_secret={api_secret}' api_friends_path = '/friends/{user_name}' api_user_info_path = '/users/{user_name}' api_user_name_info_path = '/users/{user_name}' api_user_self_info_path = '/oauth2/verify_credentials' api_team_members_path = '/orgs/{user_name}/public_members' api_friends_path = '/users/{user_id}/following' ratelimit_headers_prefix = 'x-ratelimit-' # User info extractors x_user_id = key('id') x_user_name = key('login') x_display_name = key('name') x_email = key('email') x_gravatar_id = key('gravatar_id') x_avatar_url = key('avatar_url') x_is_team = key('type', clean=lambda t: t.lower() == 'organization')
class GitLab(PlatformOAuth2): # Platform attributes name = 'gitlab' display_name = 'GitLab' fontawesome_name = name account_url = 'https://gitlab.com/{user_name}' repo_url = 'https://gitlab.com/{slug}' has_teams = True # Auth attributes # GitLab uses https://github.com/doorkeeper-gem/doorkeeper auth_url = 'https://gitlab.com/oauth/authorize' access_token_url = 'https://gitlab.com/oauth/token' oauth_default_scope = ['read_user'] # can_auth_with_client_credentials = True # https://gitlab.com/gitlab-org/gitlab-ce/issues/13795 # API attributes # http://doc.gitlab.com/ce/api/ api_format = 'json' api_paginator = header_links_paginator(total_header='X-Total') api_url = 'https://gitlab.com/api/v4' api_user_info_path = '/users/{user_id}' api_user_name_info_path = '/users?username={user_name}' api_user_self_info_path = '/user' api_team_members_path = '/groups/{user_name}/members' api_repos_path = APIEndpoint( '/users/{user_id}/projects?owned=true&visibility=public&order_by=last_activity_at&per_page=100', use_session=False) api_starred_path = APIEndpoint( '/users/{user_id}/projects?starred=true&visibility=public', use_session=False) # User info extractors x_user_id = key('id') x_user_name = key('username') x_display_name = key('name') x_email = key('email') x_avatar_url = key('avatar_url') x_description = key('bio') # Repo info extractors x_repo_id = key('id') x_repo_name = key('name') x_repo_slug = key('path_with_namespace') x_repo_description = key('description') x_repo_last_update = key('last_activity_at') x_repo_is_fork = key('forked_from_project', clean=bool) x_repo_stars_count = key('star_count') x_repo_owner_id = key('owner', clean=lambda d: d[ 'id']) # not included in responses to unauthenticated requests
class GitLab(PlatformOAuth2): # Platform attributes name = 'gitlab' display_name = 'GitLab' account_url = 'https://gitlab.com/u/{user_name}' repo_url = 'https://gitlab.com/{slug}' has_teams = True # Auth attributes # GitLab uses https://github.com/doorkeeper-gem/doorkeeper auth_url = 'https://gitlab.com/oauth/authorize' access_token_url = 'https://gitlab.com/oauth/token' can_auth_with_client_credentials = True # API attributes # http://doc.gitlab.com/ce/api/ api_format = 'json' api_paginator = header_links_paginator(total_header='X-Total') api_url = 'https://gitlab.com/api/v3' # api_user_info_path = '/users/{user_id}' # api_user_name_info_path = '/users?username={user_name}' api_user_self_info_path = '/user' # api_team_members_path = '/groups/{user_name}/members' api_repos_path = '/projects?owned=true&visibility=public&order_by=last_activity_at&per_page=100' api_starred_path = '/projects?starred=true&visibility=public' # The commented out paths are because we need this: # https://gitlab.com/gitlab-org/gitlab-ce/issues/13795 # User info extractors x_user_id = key('id') x_user_name = key('username') x_display_name = key('name') x_email = key('email') x_avatar_url = key('avatar_url') x_description = key('bio') # Repo info extractors x_repo_id = key('id') x_repo_name = key('name') x_repo_slug = key('path_with_namespace') x_repo_description = key('description') x_repo_last_update = key('last_activity_at') x_repo_is_fork = key('forked_from_project', clean=bool) x_repo_stars_count = key('star_count') x_repo_owner_id = key('owner', clean=lambda d: d['id'])
class GitHub(PlatformOAuth2): # Platform attributes name = 'github' display_name = 'GitHub' account_url = 'https://github.com/{user_name}' allows_team_connect = True # Auth attributes auth_url = 'https://github.com/login/oauth/authorize' access_token_url = 'https://github.com/login/oauth/access_token' oauth_email_scope = 'user:email' oauth_default_scope = ['read:org'] # API attributes api_format = 'json' api_paginator = header_links_paginator() api_url = 'https://api.github.com' api_user_info_path = '/user/{user_id}' api_user_name_info_path = '/users/{user_name}' api_user_self_info_path = '/user' api_team_members_path = '/orgs/{user_name}/public_members' api_friends_path = '/users/{user_name}/following' ratelimit_headers_prefix = 'x-ratelimit-' # User info extractors x_user_id = key('id') x_user_name = key('login') x_display_name = key('name') x_email = key('email') x_gravatar_id = key('gravatar_id') x_avatar_url = key('avatar_url') x_is_team = key('type', clean=lambda t: t.lower() == 'organization') def is_team_admin(self, team_name, sess): user_teams = self.api_parser(self.api_get('/user/teams', sess=sess)) return any( team.get('organization', {}).get('login') == team_name and team.get('permission') == 'admin' for team in user_teams)
class GitHub(PlatformOAuth2): # Platform attributes name = 'github' display_name = 'GitHub' account_url = 'https://github.com/{user_name}' repo_url = 'https://github.com/{slug}' has_teams = True # Auth attributes auth_url = 'https://github.com/login/oauth/authorize' access_token_url = 'https://github.com/login/oauth/access_token' oauth_email_scope = 'user:email' oauth_default_scope = ['read:org'] # API attributes api_format = 'json' api_paginator = header_links_paginator() api_url = 'https://api.github.com' api_app_auth_params = 'client_id={api_key}&client_secret={api_secret}' api_user_info_path = '/user/{user_id}' api_user_name_info_path = '/users/{user_name}' api_user_self_info_path = '/user' api_team_members_path = '/orgs/{user_name}/public_members' api_friends_path = '/users/{user_name}/following' api_repos_path = '/users/{user_name}/repos?type=owner&sort=updated&per_page=100' api_starred_path = '/users/{user_name}/starred' ratelimit_headers_prefix = 'x-ratelimit-' # User info extractors x_user_id = key('id') x_user_name = key('login') x_display_name = key('name') x_email = key('email') x_gravatar_id = key('gravatar_id') x_avatar_url = key('avatar_url') x_is_team = key('type', clean=lambda t: t.lower() == 'organization') # Repo info extractors x_repo_id = key('id') x_repo_name = key('name') x_repo_slug = key('full_name') x_repo_description = key('description') x_repo_last_update = key('updated_at') x_repo_is_fork = key('fork') x_repo_stars_count = key('stargazers_count') x_repo_owner_id = key('owner', clean=lambda d: d['id']) x_repo_extra_info_drop = drop_keys(lambda k: k.endswith('_url')) def get_CantReadMembership_url(self, **kw): return 'https://github.com/settings/connections/applications/' + self.api_key def is_team_member(self, org_name, sess, account): org_name = org_name.lower() # Check public membership first response = self.api_get('', '/orgs/' + org_name + '/public_members/' + account.user_name, sess=sess, error_handler=None) if response.status_code == 204: return True elif response.status_code != 404: self.api_error_handler(response, True, self.domain) # Check private membership response = self.api_get('', '/user/memberships/orgs/' + org_name, sess=sess, error_handler=None) if response.status_code == 403: raise CantReadMembership elif response.status_code >= 400: self.api_error_handler(response, True, self.domain) membership = self.api_parser(response) if membership['state'] == 'active': return True # Try the endpoint we were using before user_orgs = self.api_parser(self.api_get('', '/user/orgs', sess=sess)) return any(org.get('login') == org_name for org in user_orgs)
class Mastodon(PlatformOAuth2): # Platform attributes name = 'mastodon' display_name = 'Mastodon' account_url = 'https://{domain}/@{user_name}' single_domain = False def example_account_address(self, _): return _('*****@*****.**') # Auth attributes # Mastodon uses https://github.com/doorkeeper-gem/doorkeeper auth_url = 'https://{domain}/oauth/authorize' access_token_url = 'https://{domain}/oauth/token' can_auth_with_client_credentials = True # API attributes # https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md api_format = 'json' api_paginator = header_links_paginator() api_url = 'https://{domain}/api/v1' api_user_info_path = '/accounts/{user_id}' # api_user_name_info_path = '/search?q={user_name}@{domain}' api_user_self_info_path = '/accounts/verify_credentials' api_friends_path = '/accounts/{user_id}/following' ratelimit_headers_prefix = 'x-ratelimit-' # User info extractors x_domain = key('url', clean=extract_domain_from_url) x_user_id = key('id') x_user_name = key('username') x_display_name = key('display_name') x_avatar_url = key('avatar_static') def x_user_info(self, extracted, info, default): if 'accounts' in info: accounts = info.get('accounts') if accounts: return accounts[0] raise Response(404) return default def register_app(self, domain): data = { 'client_name': self.app_name, 'redirect_uris': self.callback_url.format(domain=domain), 'scopes': 'read', 'website': self.app_url, } r = requests.post('https://%s/api/v1/apps' % domain, data, timeout=self.api_timeout) status = r.status_code try: o = r.json() c_id, c_secret = o['client_id'], o['client_secret'] except (KeyError, ValueError): c_id, c_secret = None, None if status != 200 or not c_id or not c_secret: logger.error('{} responded with {}:\n{}'.format(domain, status, r.text)) msg = lambda _: _( "Is {0} really a {1} server? It is currently not acting like one.", domain, self.display_name, ) raise LazyResponse(502, msg) return c_id, c_secret