Skip to content
Snippets Groups Projects
Commit a89ebe68 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch 'bearer-token-url' into 'develop'

Bearer token url

See merge request funkwhale/funkwhale!754
parents 00169768 9c2351ba
No related branches found
No related tags found
No related merge requests found
...@@ -374,6 +374,7 @@ OAUTH2_PROVIDER = { ...@@ -374,6 +374,7 @@ OAUTH2_PROVIDER = {
"REFRESH_TOKEN_EXPIRE_SECONDS": 3600 * 24 * 15, "REFRESH_TOKEN_EXPIRE_SECONDS": 3600 * 24 * 15,
"AUTHORIZATION_CODE_EXPIRE_SECONDS": 5 * 60, "AUTHORIZATION_CODE_EXPIRE_SECONDS": 5 * 60,
"ACCESS_TOKEN_EXPIRE_SECONDS": 60 * 60 * 10, "ACCESS_TOKEN_EXPIRE_SECONDS": 60 * 60 * 10,
"OAUTH2_SERVER_CLASS": "funkwhale_api.users.oauth.server.OAuth2Server",
} }
OAUTH2_PROVIDER_APPLICATION_MODEL = "users.Application" OAUTH2_PROVIDER_APPLICATION_MODEL = "users.Application"
OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = "users.AccessToken" OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = "users.AccessToken"
......
import urllib.parse
import oauthlib.oauth2
class OAuth2Server(oauthlib.oauth2.Server):
def verify_request(self, uri, *args, **kwargs):
valid, request = super().verify_request(uri, *args, **kwargs)
if valid:
return valid, request
# maybe the token was given in the querystring?
query = urllib.parse.urlparse(request.uri).query
token = None
if query:
parsed_qs = urllib.parse.parse_qs(query)
token = parsed_qs.get("token", [])
if len(token) > 0:
token = token[0]
if token:
valid = self.request_validator.validate_bearer_token(
token, request.scopes, request
)
return valid, request
...@@ -5,7 +5,7 @@ jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER ...@@ -5,7 +5,7 @@ jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
def test_can_authenticate_using_token_param_in_url(factories, preferences, client): def test_can_authenticate_using_jwt_token_param_in_url(factories, preferences, client):
user = factories["users.User"]() user = factories["users.User"]()
preferences["common__api_authentication_required"] = True preferences["common__api_authentication_required"] = True
url = reverse("api:v1:tracks-list") url = reverse("api:v1:tracks-list")
...@@ -17,3 +17,20 @@ def test_can_authenticate_using_token_param_in_url(factories, preferences, clien ...@@ -17,3 +17,20 @@ def test_can_authenticate_using_token_param_in_url(factories, preferences, clien
token = jwt_encode_handler(payload) token = jwt_encode_handler(payload)
response = client.get(url, data={"jwt": token}) response = client.get(url, data={"jwt": token})
assert response.status_code == 200 assert response.status_code == 200
def test_can_authenticate_using_oauth_token_param_in_url(
factories, preferences, client, mocker
):
mocker.patch(
"funkwhale_api.users.oauth.permissions.should_allow", return_value=True
)
token = factories["users.AccessToken"]()
preferences["common__api_authentication_required"] = True
url = reverse("api:v1:tracks-list")
response = client.get(url)
assert response.status_code == 401
response = client.get(url, data={"token": token.token})
assert response.status_code == 200
...@@ -77,17 +77,19 @@ import TranslationsMixin from "@/components/mixins/Translations" ...@@ -77,17 +77,19 @@ import TranslationsMixin from "@/components/mixins/Translations"
export default { export default {
mixins: [TranslationsMixin], mixins: [TranslationsMixin],
props: { props: {
app: {type: Object, required: false} app: {type: Object, required: false},
defaults: {type: Object, required: false}
}, },
data() { data() {
let app = this.app || {} let app = this.app || {}
let defaults = this.defaults || {}
return { return {
isLoading: false, isLoading: false,
errors: [], errors: [],
fields: { fields: {
name: app.name || '', name: app.name || defaults.name || '',
redirect_uris: app.redirect_uris || 'urn:ietf:wg:oauth:2.0:oob', redirect_uris: app.redirect_uris || defaults.redirect_uris || 'urn:ietf:wg:oauth:2.0:oob',
scopes: app.scopes || 'read' scopes: app.scopes || defaults.scopes || 'read'
}, },
scopes: [ scopes: [
{id: "profile", icon: 'user'}, {id: "profile", icon: 'user'},
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
<translate translate-context="Content/Applications/Title">Create a new application</translate> <translate translate-context="Content/Applications/Title">Create a new application</translate>
</h2> </h2>
<application-form <application-form
:defaults="defaults"
@created="$router.push({name: 'settings.applications.edit', params: {id: $event.client_id}})" /> @created="$router.push({name: 'settings.applications.edit', params: {id: $event.client_id}})" />
</section> </section>
</div> </div>
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
import ApplicationForm from "@/components/auth/ApplicationForm" import ApplicationForm from "@/components/auth/ApplicationForm"
export default { export default {
props: ['name', 'redirect_uris', 'scopes'],
components: { components: {
ApplicationForm ApplicationForm
}, },
...@@ -26,6 +28,11 @@ export default { ...@@ -26,6 +28,11 @@ export default {
return { return {
application: null, application: null,
isLoading: false, isLoading: false,
defaults: {
name: this.name,
redirect_uris: this.redirect_uris,
scopes: this.scopes,
}
} }
}, },
computed: { computed: {
......
...@@ -104,6 +104,11 @@ export default new Router({ ...@@ -104,6 +104,11 @@ export default new Router({
{ {
path: '/settings/applications/new', path: '/settings/applications/new',
name: 'settings.applications.new', name: 'settings.applications.new',
props: (route) => ({
scopes: route.query.scopes,
name: route.query.name,
redirect_uris: route.query.redirect_uris,
}),
component: () => component: () =>
import(/* webpackChunkName: "core" */ "@/components/auth/ApplicationNew"), import(/* webpackChunkName: "core" */ "@/components/auth/ApplicationNew"),
}, },
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment