add multiple API tokens per user, removes old API tokens

This commit is contained in:
vabene1111 2022-08-04 17:24:54 +02:00
parent 9e62d8a3a3
commit 3f77b73a61
12 changed files with 666 additions and 220 deletions

View File

@ -4,6 +4,7 @@ import re
import uuid
from datetime import date, timedelta
import oauth2_provider.models
from PIL import Image
from annoying.fields import AutoOneToOneField
from django.contrib import auth
@ -63,6 +64,13 @@ auth.models.User.add_to_class('get_shopping_share', get_shopping_share)
auth.models.User.add_to_class('get_active_space', get_active_space)
def oauth_token_get_owner(self):
return self.user
oauth2_provider.models.AccessToken.add_to_class('get_owner', oauth_token_get_owner)
def get_model_name(model):
return ('_'.join(re.findall('[A-Z][^A-Z]*', model.__name__))).lower()

View File

@ -1,4 +1,5 @@
import traceback
import uuid
from datetime import datetime, timedelta
from decimal import Decimal
from gettext import gettext as _
@ -14,6 +15,7 @@ from django.utils import timezone
from django_scopes import scopes_disabled
from drf_writable_nested import UniqueFieldsMixin, WritableNestedModelSerializer
from PIL import Image
from oauth2_provider.models import AccessToken
from rest_framework import serializers
from rest_framework.exceptions import NotFound, ValidationError
@ -1134,6 +1136,27 @@ class BookmarkletImportSerializer(BookmarkletImportListSerializer):
read_only_fields = ('created_by', 'space')
# OAuth / Auth Token related Serializers
class AccessTokenSerializer(serializers.ModelSerializer):
token = serializers.SerializerMethodField('get_token')
def create(self, validated_data):
validated_data['token'] = f'tda_{str(uuid.uuid4()).replace("-","_")}'
validated_data['user'] = self.context['request'].user
return super().create(validated_data)
def get_token(self, obj):
if (timezone.now() - obj.created).seconds < 15:
return obj.token
return f'tda_************_******_***********{obj.token[len(obj.token)-4:]}'
class Meta:
model = AccessToken
fields = ('id', 'token', 'expires', 'scope', 'created', 'updated')
read_only_fields = ('id', 'token',)
# Export/Import Serializers
class KeywordExportSerializer(KeywordSerializer):

View File

@ -159,9 +159,9 @@
<br/>
{% trans 'Use the token as an Authorization header prefixed by the word token as shown in the following examples:' %}
<br/>
<code>Authorization: Token {{ api_token }}</code> {% trans 'or' %}<br/>
<code>Authorization: Bearer {{ api_token }}</code> {% trans 'or' %}<br/>
<code>curl -X GET http://your.domain.com/api/recipes/ -H 'Authorization:
Token {{ api_token }}'</code>
Bearer {{ api_token }}'</code>
</div>
</div>

View File

@ -0,0 +1,115 @@
import json
import pytest
from django.contrib import auth
from django.urls import reverse
from django.utils import timezone
from django_scopes import scopes_disabled
from oauth2_provider.models import AccessToken
from cookbook.models import ViewLog
LIST_URL = 'api:accesstoken-list'
DETAIL_URL = 'api:accesstoken-detail'
@pytest.fixture()
def obj_1(u1_s1):
return AccessToken.objects.create(user=auth.get_user(u1_s1), scope='test', expires=timezone.now() + timezone.timedelta(days=365 * 5), token='test1')
@pytest.fixture()
def obj_2(u1_s1):
return AccessToken.objects.create(user=auth.get_user(u1_s1), scope='test', expires=timezone.now() + timezone.timedelta(days=365 * 5), token='test2')
@pytest.mark.parametrize("arg", [
['a_u', 403],
['g1_s1', 200],
['u1_s1', 200],
['a1_s1', 200],
])
def test_list_permission(arg, request):
c = request.getfixturevalue(arg[0])
assert c.get(reverse(LIST_URL)).status_code == arg[1]
def test_list_space(obj_1, obj_2, u1_s1, u1_s2, space_2):
assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 2
assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 0
obj_1.user = auth.get_user(u1_s2)
obj_1.save()
assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 1
assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 1
def test_token_visibility(u1_s1, obj_1):
# tokens should only be returned on the first API request (first 15 seconds)
at = json.loads(u1_s1.get(reverse(DETAIL_URL, args=[obj_1.id])).content)
assert at['token'] == obj_1.token
with scopes_disabled():
obj_1.created = timezone.now() - timezone.timedelta(seconds=16)
obj_1.save()
at = json.loads(u1_s1.get(reverse(DETAIL_URL, args=[obj_1.id])).content)
assert at['token'] != obj_1.token
@pytest.mark.parametrize("arg", [
['a_u', 403],
['g1_s1', 404],
['u1_s1', 200],
['a1_s1', 404],
['g1_s2', 404],
['u1_s2', 404],
['a1_s2', 404],
])
def test_update(arg, request, obj_1):
c = request.getfixturevalue(arg[0])
r = c.patch(
reverse(
DETAIL_URL,
args={obj_1.id}
),
{'scope': 'lorem ipsum'},
content_type='application/json'
)
assert r.status_code == arg[1]
@pytest.mark.parametrize("arg", [
['a_u', 403],
['g1_s1', 201],
['u1_s1', 201],
['a1_s1', 201],
])
def test_add(arg, request, u1_s2, u2_s1, recipe_1_s1):
c = request.getfixturevalue(arg[0])
r = c.post(
reverse(LIST_URL),
{'scope': 'test', 'expires': timezone.now() + timezone.timedelta(days=365 * 5)},
content_type='application/json'
)
response = json.loads(r.content)
assert r.status_code == arg[1]
if r.status_code == 201:
assert response['scope'] == 'test'
def test_delete(u1_s1, u1_s2, obj_1):
r = u1_s2.delete(
reverse(
DETAIL_URL,
args={obj_1.id}
)
)
assert r.status_code == 404
r = u1_s1.delete(
reverse(
DETAIL_URL,
args={obj_1.id}
)
)
assert r.status_code == 204

View File

@ -51,6 +51,7 @@ router.register(r'user', api.UserViewSet)
router.register(r'user-preference', api.UserPreferenceViewSet)
router.register(r'user-space', api.UserSpaceViewSet)
router.register(r'view-log', api.ViewLogViewSet)
router.register(r'access-token', api.AccessTokenViewSet)
urlpatterns = [
path('', views.index, name='index'),

View File

@ -29,6 +29,7 @@ from django.utils.translation import gettext as _
from django_scopes import scopes_disabled
from icalendar import Calendar, Event
from PIL import UnidentifiedImageError
from oauth2_provider.models import AccessToken
from recipe_scrapers import scrape_html, scrape_me
from recipe_scrapers._exceptions import NoSchemaFoundInWildMode
from requests.exceptions import MissingSchema
@ -86,7 +87,7 @@ from cookbook.serializer import (AutomationSerializer, BookmarkletImportListSeri
SupermarketCategorySerializer, SupermarketSerializer,
SyncLogSerializer, SyncSerializer, UnitSerializer,
UserFileSerializer, UserSerializer, UserPreferenceSerializer,
UserSpaceSerializer, ViewLogSerializer)
UserSpaceSerializer, ViewLogSerializer, AccessTokenSerializer)
from cookbook.views.import_export import get_integration
from recipes import settings
@ -1090,6 +1091,15 @@ class CustomFilterViewSet(viewsets.ModelViewSet, StandardFilterMixin):
return super().get_queryset()
class AccessTokenViewSet(viewsets.ModelViewSet):
queryset = AccessToken.objects
serializer_class = AccessTokenSerializer
permission_classes = [CustomIsOwner]
def get_queryset(self):
return self.queryset.filter(user=self.request.user)
# -------------- DRF custom views --------------------
class AuthTokenThrottle(AnonRateThrottle):

View File

@ -1,5 +1,6 @@
import os
import re
import uuid
from datetime import datetime
from uuid import UUID
@ -18,6 +19,7 @@ from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.translation import gettext as _
from django_scopes import scopes_disabled
from oauth2_provider.models import AccessToken
from rest_framework.authtoken.models import Token
from cookbook.forms import (CommentForm, Recipe, SearchPreferenceForm, ShoppingPreferenceForm,
@ -338,8 +340,8 @@ def user_settings(request):
elif not search_error:
search_form = SearchPreferenceForm()
if (api_token := Token.objects.filter(user=request.user).first()) is None:
api_token = Token.objects.create(user=request.user)
if (api_token := AccessToken.objects.filter(user=request.user).first()) is None:
api_token = AccessToken.objects.create(user=request.user, token=f'tda_{str(uuid.uuid4()).replace("-","_")}', expires=(timezone.now() + timezone.timedelta(days=365*5)), scope='read write').token
# these fields require postgresql - just disable them if postgresql isn't available
if not settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',

View File

@ -99,6 +99,7 @@ INSTALLED_APPS = [
'django.contrib.sites',
'django.contrib.staticfiles',
'django.contrib.postgres',
'oauth2_provider',
'django_prometheus',
'django_tables2',
'corsheaders',
@ -235,10 +236,15 @@ AUTH_PASSWORD_VALIDATORS = [
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
OAUTH2_PROVIDER = {
'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'bookmarklet': 'only access to bookmarklet'}
}
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'rest_framework.authentication.BasicAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [

View File

@ -7,6 +7,7 @@ django-crispy-forms==1.14.0
django-tables2==2.4.1
djangorestframework==3.13.1
drf-writable-nested==0.6.4
django-oauth-toolkit==2.1.0
bleach==5.0.1
bleach-allowlist==1.0.3
gunicorn==20.1.0

View File

@ -1,54 +1,77 @@
<template>
<div v-if="user_preferences !== undefined">
<div>
<code>Authorization: Bearer TOKEN</code> or<br/>
<code>curl -X GET http://your.domain.com/api/recipes/ -H 'Authorization:
Bearer TOKEN'</code>
<b-list-group class="mt-3">
<b-list-group-item v-for="t in access_tokens" v-bind:key="t.id">{{ t.token }}<br/><small class="text-muted">{{
t.scope
}}
- {{ t.expires }}</small>
<b-button @click="active_token=t; generic_action = Actions.UPDATE;">Edit</b-button>
<b-button @click="active_token=t; generic_action = Actions.DELETE;">Delete</b-button>
</b-list-group-item>
</b-list-group>
<b-button @click="generic_action=Actions.CREATE">NEW</b-button>
<generic-modal-form :model="Models.ACCESS_TOKEN" :action="generic_action" :show="generic_action !== null"
:item1="active_token"
@finish-action="updateToken"/>
</div>
</template>
<script>
import {ApiApiFactory} from "@/utils/openapi/api";
import {StandardToasts} from "@/utils/utils";
import {ApiMixin, StandardToasts} from "@/utils/utils";
import axios from "axios";
import GenericModalForm from "@/components/Modals/GenericModalForm";
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
export default {
name: "APISettingsComponent",
components: {GenericModalForm},
mixins: [ApiMixin,],
props: {
user_id: Number,
},
data() {
return {
user_preferences: undefined,
languages: [],
access_tokens: [],
active_token: null,
generic_action: null,
}
},
mounted() {
this.user_preferences = this.preferences
this.languages = window.AVAILABLE_LANGUAGES
this.loadSettings()
this.loadTokens()
},
methods: {
loadSettings: function () {
loadTokens: function () {
let apiFactory = new ApiApiFactory()
apiFactory.retrieveUserPreference(this.user_id.toString()).then(result => {
this.user_preferences = result.data
apiFactory.listAccessTokens().then(result => {
this.access_tokens = result.data
}).catch(err => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_FETCH, err)
})
},
updateSettings: function (reload) {
let apiFactory = new ApiApiFactory()
apiFactory.partialUpdateUserPreference(this.user_id.toString(), this.user_preferences).then(result => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
if (reload !== undefined) {
location.reload()
updateToken: function (arg) {
if (arg !== 'cancel') {
if (this.generic_action === this.Actions.UPDATE) {
this.access_tokens[this.access_tokens.indexOf(this.active_token)] = arg.item
} else if (this.generic_action === this.Actions.CREATE) {
this.access_tokens.push(arg.item)
} else if (this.generic_action === this.Actions.DELETE) {
this.access_tokens.splice(this.access_tokens.indexOf(this.active_token), 1)
}
}).catch(err => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
})
}
this.generic_action = null
},
}
}

View File

@ -706,6 +706,31 @@ export class Models {
},
}
static ACCESS_TOKEN = {
name: "AccessToken",
apiName: "AccessToken",
paginated: false,
create: {
params: [["scope", "expires"]],
form: {
scope: {
form_field: true,
type: "text",
field: "scope",
label: "Scope",
placeholder: "",
},
expires: {
form_field: true,
type: "date",
field: "expires",
label: "expires",
placeholder: "",
},
},
},
}
static USER = {
name: "User",
apiName: "User",

View File

@ -21,6 +21,49 @@ import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObj
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base';
/**
*
* @export
* @interface AccessToken
*/
export interface AccessToken {
/**
*
* @type {number}
* @memberof AccessToken
*/
id?: number;
/**
*
* @type {string}
* @memberof AccessToken
*/
token?: string;
/**
*
* @type {string}
* @memberof AccessToken
*/
expires: string;
/**
*
* @type {string}
* @memberof AccessToken
*/
scope?: string;
/**
*
* @type {string}
* @memberof AccessToken
*/
created?: string;
/**
*
* @type {string}
* @memberof AccessToken
*/
updated?: string;
}
/**
*
* @export
@ -3893,6 +3936,39 @@ export interface ViewLog {
*/
export const ApiApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createAccessToken: async (accessToken?: AccessToken, options: any = {}): Promise<RequestArgs> => {
const localVarPath = `/api/access-token/`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(accessToken, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {Automation} [automation]
@ -4718,39 +4794,6 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
options: localVarRequestOptions,
};
},
/**
*
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createUser: async (user?: User, options: any = {}): Promise<RequestArgs> => {
const localVarPath = `/api/user/`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(user, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} name
@ -4917,6 +4960,39 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
destroyAccessToken: async (id: string, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('destroyAccessToken', 'id', id)
const localVarPath = `/api/access-token/{id}/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -5733,39 +5809,6 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
destroyUser: async (id: string, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('destroyUser', 'id', id)
const localVarPath = `/api/user/{id}/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
@ -5921,6 +5964,35 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
options: localVarRequestOptions,
};
},
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
listAccessTokens: async (options: any = {}): Promise<RequestArgs> => {
const localVarPath = `/api/access-token/`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {*} [options] Override http request option.
@ -7461,6 +7533,43 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
partialUpdateAccessToken: async (id: string, accessToken?: AccessToken, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('partialUpdateAccessToken', 'id', id)
const localVarPath = `/api/access-token/{id}/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(accessToken, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -8666,6 +8775,39 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
retrieveAccessToken: async (id: string, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('retrieveAccessToken', 'id', id)
const localVarPath = `/api/access-token/{id}/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
@ -9937,6 +10079,43 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateAccessToken: async (id: string, accessToken?: AccessToken, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('updateAccessToken', 'id', id)
const localVarPath = `/api/access-token/{id}/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(accessToken, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -10862,43 +11041,6 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateUser: async (id: string, user?: User, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('updateUser', 'id', id)
const localVarPath = `/api/user/{id}/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(user, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} id A unique integer value identifying this user file.
@ -11017,6 +11159,16 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosParamCreator = ApiApiAxiosParamCreator(configuration)
return {
/**
*
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async createAccessToken(accessToken?: AccessToken, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AccessToken>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.createAccessToken(accessToken, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {Automation} [automation]
@ -11267,16 +11419,6 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.createUnit(unit, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async createUser(user?: User, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<User>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.createUser(user, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} name
@ -11322,6 +11464,16 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.createrecipeFromSource(body, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async destroyAccessToken(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.destroyAccessToken(id, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -11572,16 +11724,6 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.destroyUnit(id, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async destroyUser(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.destroyUser(id, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this user file.
@ -11624,6 +11766,15 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.imageRecipe(id, image, imageUrl, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async listAccessTokens(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AccessToken>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.listAccessTokens(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {*} [options] Override http request option.
@ -12063,6 +12214,17 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.moveKeyword(id, parent, keyword, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async partialUpdateAccessToken(id: string, accessToken?: AccessToken, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AccessToken>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.partialUpdateAccessToken(id, accessToken, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -12419,6 +12581,16 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.relatedRecipe(id, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async retrieveAccessToken(id: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AccessToken>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.retrieveAccessToken(id, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -12801,6 +12973,17 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.shoppingRecipe(id, recipeShoppingUpdate, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateAccessToken(id: string, accessToken?: AccessToken, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AccessToken>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.updateAccessToken(id, accessToken, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -13076,17 +13259,6 @@ export const ApiApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.updateUnit(id, unit, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateUser(id: string, user?: User, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<User>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.updateUser(id, user, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @param {string} id A unique integer value identifying this user file.
@ -13124,6 +13296,15 @@ export const ApiApiFp = function(configuration?: Configuration) {
export const ApiApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
const localVarFp = ApiApiFp(configuration)
return {
/**
*
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createAccessToken(accessToken?: AccessToken, options?: any): AxiosPromise<AccessToken> {
return localVarFp.createAccessToken(accessToken, options).then((request) => request(axios, basePath));
},
/**
*
* @param {Automation} [automation]
@ -13349,15 +13530,6 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
createUnit(unit?: Unit, options?: any): AxiosPromise<Unit> {
return localVarFp.createUnit(unit, options).then((request) => request(axios, basePath));
},
/**
*
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createUser(user?: User, options?: any): AxiosPromise<User> {
return localVarFp.createUser(user, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} name
@ -13399,6 +13571,15 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
createrecipeFromSource(body?: any, options?: any): AxiosPromise<any> {
return localVarFp.createrecipeFromSource(body, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
destroyAccessToken(id: string, options?: any): AxiosPromise<void> {
return localVarFp.destroyAccessToken(id, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -13624,15 +13805,6 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
destroyUnit(id: string, options?: any): AxiosPromise<void> {
return localVarFp.destroyUnit(id, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
destroyUser(id: string, options?: any): AxiosPromise<void> {
return localVarFp.destroyUser(id, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this user file.
@ -13671,6 +13843,14 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
imageRecipe(id: string, image?: any, imageUrl?: string, options?: any): AxiosPromise<RecipeImage> {
return localVarFp.imageRecipe(id, image, imageUrl, options).then((request) => request(axios, basePath));
},
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
listAccessTokens(options?: any): AxiosPromise<Array<AccessToken>> {
return localVarFp.listAccessTokens(options).then((request) => request(axios, basePath));
},
/**
*
* @param {*} [options] Override http request option.
@ -14070,6 +14250,16 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
moveKeyword(id: string, parent: string, keyword?: Keyword, options?: any): AxiosPromise<Keyword> {
return localVarFp.moveKeyword(id, parent, keyword, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
partialUpdateAccessToken(id: string, accessToken?: AccessToken, options?: any): AxiosPromise<AccessToken> {
return localVarFp.partialUpdateAccessToken(id, accessToken, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -14394,6 +14584,15 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
relatedRecipe(id: string, options?: any): AxiosPromise<RecipeSimple> {
return localVarFp.relatedRecipe(id, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
retrieveAccessToken(id: string, options?: any): AxiosPromise<AccessToken> {
return localVarFp.retrieveAccessToken(id, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -14738,6 +14937,16 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
shoppingRecipe(id: string, recipeShoppingUpdate?: RecipeShoppingUpdate, options?: any): AxiosPromise<RecipeShoppingUpdate> {
return localVarFp.shoppingRecipe(id, recipeShoppingUpdate, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateAccessToken(id: string, accessToken?: AccessToken, options?: any): AxiosPromise<AccessToken> {
return localVarFp.updateAccessToken(id, accessToken, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -14988,16 +15197,6 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
updateUnit(id: string, unit?: Unit, options?: any): AxiosPromise<Unit> {
return localVarFp.updateUnit(id, unit, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateUser(id: string, user?: User, options?: any): AxiosPromise<User> {
return localVarFp.updateUser(id, user, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} id A unique integer value identifying this user file.
@ -15033,6 +15232,17 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
* @extends {BaseAPI}
*/
export class ApiApi extends BaseAPI {
/**
*
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public createAccessToken(accessToken?: AccessToken, options?: any) {
return ApiApiFp(this.configuration).createAccessToken(accessToken, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {Automation} [automation]
@ -15308,17 +15518,6 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).createUnit(unit, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public createUser(user?: User, options?: any) {
return ApiApiFp(this.configuration).createUser(user, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} name
@ -15368,6 +15567,17 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).createrecipeFromSource(body, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public destroyAccessToken(id: string, options?: any) {
return ApiApiFp(this.configuration).destroyAccessToken(id, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -15643,17 +15853,6 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).destroyUnit(id, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public destroyUser(id: string, options?: any) {
return ApiApiFp(this.configuration).destroyUser(id, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this user file.
@ -15700,6 +15899,16 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).imageRecipe(id, image, imageUrl, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public listAccessTokens(options?: any) {
return ApiApiFp(this.configuration).listAccessTokens(options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {*} [options] Override http request option.
@ -16179,6 +16388,18 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).moveKeyword(id, parent, keyword, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public partialUpdateAccessToken(id: string, accessToken?: AccessToken, options?: any) {
return ApiApiFp(this.configuration).partialUpdateAccessToken(id, accessToken, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -16567,6 +16788,17 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).relatedRecipe(id, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public retrieveAccessToken(id: string, options?: any) {
return ApiApiFp(this.configuration).retrieveAccessToken(id, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -16987,6 +17219,18 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).shoppingRecipe(id, recipeShoppingUpdate, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this access token.
* @param {AccessToken} [accessToken]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public updateAccessToken(id: string, accessToken?: AccessToken, options?: any) {
return ApiApiFp(this.configuration).updateAccessToken(id, accessToken, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this automation.
@ -17287,18 +17531,6 @@ export class ApiApi extends BaseAPI {
return ApiApiFp(this.configuration).updateUnit(id, unit, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this user.
* @param {User} [user]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiApi
*/
public updateUser(id: string, user?: User, options?: any) {
return ApiApiFp(this.configuration).updateUser(id, user, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} id A unique integer value identifying this user file.