aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2021-01-31 19:23:00 +0100
committerneodarz <neodarz@neodarz.net>2021-01-31 19:23:42 +0100
commit2575ee029ca41f4bc9777b40dade3da9962b22ae (patch)
treefc636745a06be511218896af59d914cbb2e7d7c1
parent72727d09d0d45c9ca8c043954cf89c498ee36304 (diff)
downloadpyfunkwhale-2575ee029ca41f4bc9777b40dade3da9962b22ae.tar.xz
pyfunkwhale-2575ee029ca41f4bc9777b40dade3da9962b22ae.zip
Add plain HTTP authentification
-rw-r--r--README.md88
-rw-r--r--pyfunkwhale/client.py76
-rw-r--r--pyfunkwhale/funkwhale.py9
3 files changed, 116 insertions, 57 deletions
diff --git a/README.md b/README.md
index 41fe849..a798c1e 100644
--- a/README.md
+++ b/README.md
@@ -17,12 +17,47 @@ pip install -r requirements.txt
# Use
-This client library use th OAuth2 Authorization Code flow and ask to the user
-to authorize this app. I'm not ok with how I do this for the moment. If you
-have suggestion about how to do this, I will gladly accept to discuse it.
-And you can also send me suggestions for other parts of this module ;)
+First you to select an authentification method, two are actually available
+Plain HTTP and OAuth2.
-Example usage:
+## Plain HTTP authentification
+
+```
+#!/usr/bin/env python
+# -*- condig: utf-8 -*-
+
+from pyfunkwhale.funkwhale import Funkwhale
+from pyfunkwhale.client import InvalidTokenError
+
+client_name = "pyfunkwhale"
+
+redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
+
+# This is your instance and login information
+username = "demo"
+password = "demo"
+domain = "https://demo.funkwhale.audio"
+
+authorization_endpoint = domain + "/authorize"
+login_endpoint = domain + "/api/v1/oauth/token/"
+
+login_endpoint = domain + "/api/v1/token/"
+
+funkwhale = Funkwhale(
+ client_name,
+ redirect_uri,
+ username,
+ password,
+ domain,
+ login_endpoint,
+)
+
+artists = funkwhale.albums()
+
+print(artists)
+```
+
+## OAuth2 Authorization Code flow
```
#!/usr/bin/env python
@@ -48,9 +83,8 @@ domain = "https://demo.funkwhale.audio"
scopes = "read"
-authorization_endpoint = "https://demo.funkwhale.audio/authorize"
-token_endpoint = "https://demo.funkwhale.audio/api/v1/oauth/token/"
-
+authorization_endpoint = domain + "/authorize"
+login_endpoint = domain + "/api/v1/oauth/token/"
# Save the OAuth2 infos in file, this is ugly yup
token_filename = 'oauth_token.data'
@@ -61,9 +95,19 @@ def _ask_new_auth(funkwhale, message):
authorization_code = input("Enter response code: ")
funkwhale.client._set_token(authorization_code)
-funkwhale = Funkwhale(client_name, redirect_uri, client_id, client_secret,
- scopes, username, password, domain, authorization_endpoint,
- token_endpoint, token_filename)
+funkwhale = Funkwhale(
+ client_name,
+ redirect_uri,
+ username,
+ password,
+ domain,
+ login_endpoint,
+ client_secret,
+ scopes,
+ client_id,
+ authorization_endpoint,
+ token_filename,
+)
try:
artists = funkwhale.artists()
@@ -72,13 +116,14 @@ except InvalidTokenError as e:
artists = funkwhale.artists()
print(artists)
+```
-# In case you ask, their is an example for downloading a song
-try:
- r = funkwhale.listen("f9d02c64-bafa-43cb-8e1e-fa612e7c5dab")
-except InvalidTokenError as e:
- _ask_new_auth(funkwhale, e.message)
- r = funkwhale.rate_limit()
+## Examples
+
+In case you ask, their is an example for downloading a song
+
+```
+r = funkwhale.listen("f9d02c64-bafa-43cb-8e1e-fa612e7c5dab")
with open('/tmp/test.mp3', 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
@@ -91,9 +136,12 @@ with open('/tmp/test.mp3', 'wb') as f:
List of features implemented or planned:
- [/] Auth
- - [x] Login with OAuth2 Authorization Code flow
- - [x] Register an OAuth2 application
- - [x] Get an JWT token
+ - [x] OAuth2 Authorization Code flow
+ - [x] Login
+ - [x] Register an application
+ - [x] Get an JWT token
+ - [x] Simple Authentication
+ - [x] Login
- [ ] Create an account
- [ ] Request a password request
- [x] Retrieve user information
diff --git a/pyfunkwhale/client.py b/pyfunkwhale/client.py
index a2f5b57..9e0b72c 100644
--- a/pyfunkwhale/client.py
+++ b/pyfunkwhale/client.py
@@ -4,6 +4,7 @@
import json
import re
from time import time
+import requests
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2.rfc6749.errors import InvalidScopeError
from requests.models import Response
@@ -21,31 +22,39 @@ class InvalidTokenError(Exception):
class Client(object):
- def __init__(self, client_name, redirect_uri, client_id,
- client_secret, scopes, username, password, domain,
- authorization_endpoint, token_endpoint,
- token_filename):
+ def __init__(self, client_name, redirect_uri, username, password, domain,
+ login_endpoint, client_secret = None, scopes = None,
+ client_id = None, authorization_endpoint = None,
+ token_filename = None):
+
self.client_name = client_name
self.redirect_uri = redirect_uri
- self.client_id = client_id
- self.client_secret = client_secret
- self.scopes = scopes
self.token = None
self.username = username
self.password = password
self.domain = domain
- self.authorization_endpoint = authorization_endpoint
- self.token_endpoint = token_endpoint
- self.token_filename = token_filename
- self.oauth_client = OAuth2Session(
- self.client_id,
- redirect_uri=self.redirect_uri,
- scope=self.scopes)
- self.authorization_url, self.state = self.oauth_client. \
- authorization_url(
- self.authorization_endpoint)
+ self.login_endpoint = login_endpoint
+
+ if 'oauth' not in self.login_endpoint:
+ self.session = requests.Session()
+ self.session.auth = (username, password)
+
+ self.session.get(self.domain + '/api/v1/token/')
+ else:
+ self.client_secret = client_secret
+ self.scopes = scopes
+ self.client_id = client_id
+ self.authorization_endpoint = authorization_endpoint
+ self.token_filename = token_filename
+ self.oauth_client = OAuth2Session(
+ self.client_id,
+ redirect_uri=self.redirect_uri,
+ scope=self.scopes)
+ self.authorization_url, self.state = self.oauth_client. \
+ authorization_url(
+ self.authorization_endpoint)
def _connect(self):
"""
@@ -64,7 +73,7 @@ class Client(object):
self.authorization_code = authorization_code
self.token = self.oauth_client.fetch_token(
- self.token_endpoint,
+ self.login_endpoint,
code=self.authorization_code,
client_secret=self.client_secret)
write_file(self.token_filename, self.token)
@@ -77,7 +86,7 @@ class Client(object):
if time() - 60 > self.token["expires_at"]:
try:
self.token = self.oauth_client.refresh_token(
- self.token_endpoint,
+ self.login_endpoint,
refresh_token=self.token["refresh_token"],
client_id=self.client_id,
client_secret=self.client_secret)
@@ -122,21 +131,28 @@ class Client(object):
pyfunkwhale.client.InvalidTokenError
If current token is invalid
"""
- self._refresh_token()
- if headers is None:
- headers = {'Authorization': self.token['token_type'] + ' ' +
- self.token['access_token']}
+ if getattr(self, 'oauth_client', False):
+ self._refresh_token()
+ if headers is None:
+ headers = {'Authorization': self.token['token_type'] + ' ' +
+ self.token['access_token']}
- _call = getattr(self.oauth_client, method)
+ _call = getattr(self.oauth_client, method)
- endpoint = re.sub(r'^\/', '', endpoint)
+ endpoint = re.sub(r'^\/', '', endpoint)
- r = _call(self.domain + '/api/v1/' + endpoint, headers=headers,
- params=params, data=data)
+ r = _call(self.domain + '/api/v1/' + endpoint, headers=headers,
+ params=params, data=data)
- if r.status_code == 401:
- raise InvalidTokenError(self)
+ if r.status_code == 401:
+ raise InvalidTokenError(self)
+
+ r.raise_for_status()
+ else:
+ _call = getattr(self.session, method)
+ r = _call(self.domain + '/api/v1/' + endpoint, headers=headers,
+ params=params, data=data)
- r.raise_for_status()
+ r.raise_for_status()
return r
diff --git a/pyfunkwhale/funkwhale.py b/pyfunkwhale/funkwhale.py
index 1faf788..47e6b84 100644
--- a/pyfunkwhale/funkwhale.py
+++ b/pyfunkwhale/funkwhale.py
@@ -7,13 +7,8 @@ from pyfunkwhale.client import Client
class Funkwhale(object):
- def __init__(self, client_name, redirect_uri, client_id,
- client_secret, scopes, username, password, domain,
- authorization_endpoint, token_endpoint, token_filename):
- self.client = Client(
- client_name, redirect_uri, client_id, client_secret,
- scopes, username, password, domain, authorization_endpoint,
- token_endpoint, token_filename)
+ def __init__(self, *args, **kwargs):
+ self.client = Client(*args, **kwargs)
def _build_params(self, arguments: dict) -> dict:
"""