xeauth
Advanced tools
+2
-2
| Metadata-Version: 2.1 | ||
| Name: xeauth | ||
| Version: 0.2.0 | ||
| Version: 0.2.1 | ||
| Summary: Top-level package for xeauth. | ||
@@ -24,3 +24,3 @@ Home-page: https://github.com/jmosbacher/xeauth | ||
| Requires-Dist: gnupg (>=2.3.1,<3.0.0) | ||
| Requires-Dist: httpx (>=0.19,<0.23) | ||
| Requires-Dist: httpx (>=0.19,<0.25) | ||
| Requires-Dist: param (>=1.12.0,<2.0.0) | ||
@@ -27,0 +27,0 @@ Requires-Dist: rich (>=13.1.0,<14.0.0) |
+2
-2
| [tool] | ||
| [tool.poetry] | ||
| name = "xeauth" | ||
| version = "0.2.0" | ||
| version = "0.2.1" | ||
| homepage = "https://github.com/jmosbacher/xeauth" | ||
@@ -27,3 +27,3 @@ description = "Top-level package for xeauth." | ||
| click = "*" | ||
| httpx = ">=0.19,<0.23" | ||
| httpx = ">=0.19,<0.25" | ||
| appdirs = "^1.4.4" | ||
@@ -30,0 +30,0 @@ param = "^1.12.0" |
+2
-2
@@ -14,3 +14,3 @@ # -*- coding: utf-8 -*- | ||
| 'gnupg>=2.3.1,<3.0.0', | ||
| 'httpx>=0.19,<0.23', | ||
| 'httpx>=0.19,<0.25', | ||
| 'param>=1.12.0,<2.0.0', | ||
@@ -26,3 +26,3 @@ 'rich>=13.1.0,<14.0.0'] | ||
| 'name': 'xeauth', | ||
| 'version': '0.2.0', | ||
| 'version': '0.2.1', | ||
| 'description': 'Top-level package for xeauth.', | ||
@@ -29,0 +29,0 @@ 'long_description': '======\nxeauth\n======\n\n\n.. image:: https://img.shields.io/pypi/v/xeauth.svg\n :target: https://pypi.python.org/pypi/xeauth\n\n.. image:: https://img.shields.io/travis/jmosbacher/xeauth.svg\n :target: https://travis-ci.com/jmosbacher/xeauth\n\n.. image:: https://readthedocs.org/projects/xeauth/badge/?version=latest\n :target: https://xeauth.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n\n\n\nAuthentication client for the Xenon edark matter experiment.\n\n\n* Free software: MIT\n* Documentation: https://xeauth.readthedocs.io.\n\n\nFeatures\n--------\n\n* TODO\n\nCredits\n-------\n\nThis package was created with Cookiecutter_ and the `briggySmalls/cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`briggySmalls/cookiecutter-pypackage`: https://github.com/briggySmalls/cookiecutter-pypackage\n', |
@@ -11,2 +11,2 @@ """Top-level package for xeauth.""" | ||
| __email__ = "joe.mosbacher@gmail.com" | ||
| __version__ = "0.2.0" | ||
| __version__ = "0.2.1" |
+77
-13
@@ -7,7 +7,57 @@ from contextlib import contextmanager | ||
| from .settings import config | ||
| from .user import XenonUser | ||
| class GitHubUser(param.Parameterized): | ||
| login = param.String(doc="The Github username of the user.") | ||
| name = param.String(doc="The full name of the user.") | ||
| email = param.String(doc="The email address of the user.") | ||
| avatar_url = param.String(doc="The URL of the user's avatar.") | ||
| github_id = param.Integer(doc="The Github ID of the user.") | ||
| organizations = param.List(doc="The Github organizations the user is a member of.", default=[]) | ||
| teams = param.List(doc="The Github teams the user is a member of.", default=[]) | ||
| @classmethod | ||
| def from_github_auth(cls, auth): | ||
| """ | ||
| Creates a GithubUser from a GithubAuth. | ||
| Args: | ||
| auth (GithubAuth): The GithubAuth. | ||
| Returns: | ||
| GithubUser: The GithubUser. | ||
| """ | ||
| api = auth.api | ||
| profile = api.profile | ||
| data = {k: v for k,v in profile.items() if k in cls.param.params()} | ||
| data['github_id'] = profile.pop('id', None) | ||
| data['organizations'] = api.organizations | ||
| data['teams'] = auth.api.teams | ||
| return cls(**data) | ||
| @classmethod | ||
| def from_github_token(cls, token): | ||
| """ | ||
| Creates a GithubUser from a Github token. | ||
| Args: | ||
| token (str): The Github token. | ||
| Returns: | ||
| GithubUser: The GithubUser. | ||
| """ | ||
| from xeauth.github import GitHubAuth | ||
| auth = GitHubAuth(oauth_token=token) | ||
| return cls.from_github_auth(auth) | ||
| class GitHubApi(param.Parameterized): | ||
| API_URL = 'https://api.github.com' | ||
| _cache = param.Dict(doc="A cache of Github API responses.", default={}) | ||
| oauth_token = param.String() | ||
@@ -27,6 +77,10 @@ | ||
| def get(self, path, *args, **kwargs): | ||
| if path in self._cache: | ||
| return self._cache[path] | ||
| with self.Client() as client: | ||
| response = client.get(path, *args, **kwargs) | ||
| response.raise_for_status() | ||
| return response.json() | ||
| data = response.json() | ||
| self._cache[path] = data | ||
| return data | ||
@@ -75,2 +129,5 @@ def post(self, path, *args, **kwargs): | ||
| @property | ||
| def ssh_keys(self): | ||
| return self.get('/user/keys') | ||
@@ -90,7 +147,2 @@ class GitHubDeviceCode(param.Parameterized): | ||
| @classmethod | ||
| def from_response_data(cls, client_id, data): | ||
| return cls(**data) | ||
| def open_browser(self): | ||
@@ -129,5 +181,5 @@ import webbrowser | ||
| class GithubAuth(param.Parameterized): | ||
| class GitHubAuth(param.Parameterized): | ||
| BASE_URL = 'https://github.com/login' | ||
| DEFAULT_SCOPES = ("read:org", "read:user") | ||
| DEFAULT_SCOPES = ("read:org", "read:user", "read:public_key", "user:email", "read:gpg_key") | ||
@@ -166,9 +218,13 @@ oauth_token = param.String() | ||
| @classmethod | ||
| def device_login(cls, client_id, scopes=None, console=None): | ||
| def device_login(cls, client_id=None, scopes=None, console=None): | ||
| if console is None: | ||
| console = Console() | ||
| code = cls.get_device_code(client_id, scopes=scopes) | ||
| console.print(code.prompt) | ||
| code = cls.get_device_code(client_id=client_id, scopes=scopes) | ||
| prompt = (f"Please visit [link={code.verification_uri}]" | ||
| f"{code.verification_uri} [/link]" | ||
| f"and enter the code: {code.user_code}") | ||
| console.print(prompt) | ||
| token = code.await_token() | ||
| return cls(client_id=client_id, oauth_token=token) | ||
| return cls(oauth_token=token) | ||
@@ -191,2 +247,10 @@ @contextmanager | ||
| @property | ||
| def user(self): | ||
| return GitHubUser.from_github_auth(self) | ||
| @property | ||
| def xenon_user(self): | ||
| return XenonUser.from_github_username(self.api.username) | ||
| @property | ||
| def xenonnt_member(self): | ||
@@ -193,0 +257,0 @@ return "XENONnT" in self.api.organizations |
+11
-17
| import param | ||
| from .github import GithubAuth | ||
| from .settings import config | ||
@@ -15,3 +14,3 @@ | ||
| email = param.String(doc="The email address of the user.") | ||
| full_name = param.String(doc="The full name of the user.", default=None) | ||
| name = param.String(doc="The full name of the user.", default=None) | ||
| github = param.String(doc="The Github username of the user.", default=None) | ||
@@ -28,12 +27,11 @@ cell = param.String(doc="The cell phone number of the user.", default=None) | ||
| last_name = param.String(doc="The last name of the user.", default=None) | ||
| github_orgs = param.List(doc="The Github organizations the user is a member of.", default=[]) | ||
| github_teams = param.List(doc="The Github teams the user is a member of.", default=[]) | ||
| @classmethod | ||
| def from_github_token(cls, token): | ||
| def from_github_username(cls, username): | ||
| """ | ||
| Creates a XenonUser from a Github token. | ||
| Creates a XenonUser from a Github username. | ||
| Args: | ||
| token (str): The Github token. | ||
| username (str): The Github username. | ||
@@ -44,16 +42,12 @@ Returns: | ||
| users_db = config.mongo_collection('users') | ||
| api = GithubAuth(oauth_token=token).api | ||
| github_user = api.username | ||
| teams = api.teams | ||
| orgs = api.organizations | ||
| data = users_db.find_one({'github': github_user}) | ||
| data = users_db.find_one({'github': username}) | ||
| if data is None: | ||
| raise ValueError(f'User {github_user} not found in Xenon database.') | ||
| data['full_name'] = data.get('name', data.get('first_name', '') + ' ' + data.get('last_name', '')) | ||
| raise ValueError(f'User {username} not found in Xenon database.') | ||
| if not data.get('name'): | ||
| data['name'] = data.get('first_name', '') + ' ' + data.get('last_name', '') | ||
| data['active'] = data.get('active', False) in [True, 'True', 'true'] | ||
| data['github_teams'] = teams | ||
| data['github_orgs'] = orgs | ||
| data = {k: v for k,v in data.items() if k in cls.param.params()} | ||
| return cls(**data) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
28249
6.37%570
8.16%