diff --git a/.gitignore b/.gitignore index ee11984..c134ff3 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,6 @@ dmypy.json .pyre/ # Del .idea -.idea/ \ No newline at end of file +.idea/ + +test*.py \ No newline at end of file diff --git a/gitflic/__init__.py b/gitflic/__init__.py index e69de29..41bff03 100644 --- a/gitflic/__init__.py +++ b/gitflic/__init__.py @@ -0,0 +1,2 @@ +from .api import Gitflic +from .auth import GitflicAuthScopes, GitflicAuth diff --git a/gitflic/api.py b/gitflic/api.py index 5041b69..443ea7e 100644 --- a/gitflic/api.py +++ b/gitflic/api.py @@ -1,6 +1,9 @@ +import requests + +API_URL = 'https://api.gitflic.ru/' + class Gitflic: def __init__(self): pass - \ No newline at end of file diff --git a/gitflic/auth.py b/gitflic/auth.py new file mode 100644 index 0000000..4e1f3de --- /dev/null +++ b/gitflic/auth.py @@ -0,0 +1,97 @@ +from enum import Enum +import logging +from typing import Union +import webbrowser +import urllib.parse + +import requests + +from .exceptions import AuthError, GitflicExceptions + +oauth_url = "https://oauth.gitflic.ru/oauth/authorize?scope={}&clientId={}&redirectUrl={}&state={}" + + +class GitflicAuthScopes(Enum): + USER_READ = "USER_READ" + USER_WRITE = "USER_WRITE" + PROJECT_READ = "PROJECT_READ" + PROJECT_WRITE = "PROJECT_WRITE" + PROJECT_EDIT = "PROJECT_EDIT" + + ALL = "USER_READ,USER_WRITE,PROJECT_READ,PROJECT_WRITE,PROJECT_EDIT" + + +class GitflicAuth: + + # noinspection PyTypeChecker + def __init__(self, + access_token: str = None, + scope: Union[GitflicAuthScopes, str] = None, + client_id: str = None, + redirect_url: str = None, + state: str = None): + """ + + :param access_token: + :param scope: + :param client_id: + :param redirect_url: + """ + + self.log: logging.Logger = logging.getLogger(__name__) + + self.session: requests.Session = requests.Session() + + self.access_token: str = access_token + + self.scope: str = scope if not isinstance(scope, GitflicAuthScopes) else scope.value + self.client_id: str = client_id + self.redirect_url: str = redirect_url + self.state = state + + self.refresh_token: str = None + + if any((access_token, scope, client_id, redirect_url, state)): + if access_token: + pass + elif not (scope and client_id and redirect_url, state): + raise GitflicExceptions( + "Cannot auth without 'scope', 'client_id', 'redirect_url', 'state' parameters. " + "See doc: https://gitflic.ru/help/api/access-token." + ) + else: + raise GitflicExceptions( + "Cannot auth without 'token' or 'scope' and 'client_id' and 'redirect_url' and 'state' parameters. " + "See doc: https://gitflic.ru/help/api/access-token." + ) + + self._login() + + def _login(self): + self.log.debug("Trying to login.") + + if self.access_token: + self.session.headers.update({"Authorization": "token " + self.access_token}) + else: + + raise GitflicExceptions("Oauth not ready. Use access_token.") + + # redirect_url = urllib.parse.quote_plus(self.redirect_url) + # webbrowser.open(oauth_url.format(self.scope, self.client_id, redirect_url, self.state)) + # url = input("Paste redirect url: ") + # r = self.session.get("").json() + # print(r) + + # self.session.headers.update({"Authorization": "token " + "null"}) + + self.check_token() + + def check_token(self): + self.log.debug("Check token.") + r = self.session.get("https://api.gitflic.ru/user/me") + + if r.status_code == 403: + raise AuthError("Authentication failed.") + else: + r = r.json() + self.log.debug(f"Logged as {r.get('username')} {r.get('id')}") diff --git a/gitflic/exceptions.py b/gitflic/exceptions.py new file mode 100644 index 0000000..44fe072 --- /dev/null +++ b/gitflic/exceptions.py @@ -0,0 +1,22 @@ +class GitflicExceptions(Exception): + error_code: int = 1 + reason: str = None + reason_ru: str = None + + +class AuthError(GitflicExceptions): + error_code = 403 + reason = None + reason_ru = None + + +class NoRights(GitflicExceptions): + error_code = 403 + reason = "Нет прав для доступа." + reason_ru = "There are no access rights." + + +class NotFound(GitflicExceptions): + error_code = 404 + reason = "No data was found for the query." + reason_ru = "Данные по запросу не найдены."