diff --git a/shynet/api/admin.py b/shynet/api/admin.py
index 4b08f5a..d3c1eff 100644
--- a/shynet/api/admin.py
+++ b/shynet/api/admin.py
@@ -1,9 +1 @@
-from django.contrib import admin
-from api.models import ApiToken
-
-
-class ApiTokenAdmin(admin.ModelAdmin):
- list_display = ("name", "user", "value")
-
-
-admin.site.register(ApiToken, ApiTokenAdmin)
+# from django.contrib import admin
diff --git a/shynet/api/migrations/0001_initial.py b/shynet/api/migrations/0001_initial.py
deleted file mode 100644
index b6ebdc0..0000000
--- a/shynet/api/migrations/0001_initial.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generated by Django 3.2.5 on 2021-10-11 09:31
-
-import api.models
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name='ApiToken',
- fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=64)),
- ('value', models.TextField(default=api.models._default_token_value, unique=True)),
- ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='api_tokens', to=settings.AUTH_USER_MODEL)),
- ],
- options={
- 'ordering': ['name', 'value'],
- },
- ),
- ]
diff --git a/shynet/api/mixins.py b/shynet/api/mixins.py
index 380e009..47dc9a8 100644
--- a/shynet/api/mixins.py
+++ b/shynet/api/mixins.py
@@ -1,6 +1,7 @@
from django.http import JsonResponse
from django.contrib.auth.models import AnonymousUser
-from .models import ApiToken
+
+from core.models import User
class ApiTokenRequiredMixin:
@@ -10,11 +11,9 @@ class ApiTokenRequiredMixin:
return AnonymousUser()
token = token.split(' ')[1]
- api_token = ApiToken.objects.filter(value=token).first()
- if not api_token:
- return AnonymousUser()
+ user = User.objects.filter(api_token=token).first()
- return api_token.user
+ return user if user else AnonymousUser()
def dispatch(self, request, *args, **kwargs):
request.user = self._get_user_by_token(request)
diff --git a/shynet/api/models.py b/shynet/api/models.py
index 800f726..24e1689 100644
--- a/shynet/api/models.py
+++ b/shynet/api/models.py
@@ -1,19 +1 @@
-from django.db import models
-from core.models import User
-from secrets import token_urlsafe
-
-
-def _default_token_value():
- return token_urlsafe(32)
-
-
-class ApiToken(models.Model):
- name = models.CharField(max_length=64)
- value = models.TextField(default=_default_token_value, unique=True)
- user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="api_tokens")
-
- class Meta:
- ordering = ["name", "value"]
-
- def __str__(self):
- return self.name
+# from django.db import models
diff --git a/shynet/core/migrations/0009_auto_20211117_0217.py b/shynet/core/migrations/0009_auto_20211117_0217.py
new file mode 100644
index 0000000..461cd1e
--- /dev/null
+++ b/shynet/core/migrations/0009_auto_20211117_0217.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.2.5 on 2021-11-17 07:17
+
+import core.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('core', '0008_auto_20200628_1403'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='api_token',
+ field=models.TextField(default=core.models._default_api_token, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='user',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ ]
diff --git a/shynet/core/models.py b/shynet/core/models.py
index 9f78b00..875faba 100644
--- a/shynet/core/models.py
+++ b/shynet/core/models.py
@@ -1,8 +1,9 @@
import ipaddress
-import json
import re
import uuid
+from secrets import token_urlsafe
+
from django.apps import apps
from django.conf import settings
from django.contrib.auth.models import AbstractUser
@@ -43,9 +44,14 @@ def _parse_network_list(networks: str):
return [ipaddress.ip_network(network.strip()) for network in networks.split(",")]
+def _default_api_token():
+ return token_urlsafe(32)
+
+
class User(AbstractUser):
username = models.TextField(default=_default_uuid, unique=True)
email = models.EmailField(unique=True)
+ api_token = models.TextField(default=_default_api_token, unique=True)
def __str__(self):
return self.email
diff --git a/shynet/dashboard/templates/base.html b/shynet/dashboard/templates/base.html
index f4d2f67..113d602 100644
--- a/shynet/dashboard/templates/base.html
+++ b/shynet/dashboard/templates/base.html
@@ -88,6 +88,9 @@
{% url 'account_set_password' as url %}
{% include 'dashboard/includes/sidebar_portal.html' with label="Security" url=url %}
+ {% url 'dashboard:api_settings' as url %}
+ {% include 'dashboard/includes/sidebar_portal.html' with label="API" url=url %}
+
{% url 'account_logout' as url %}
{% include 'dashboard/includes/sidebar_portal.html' with label="Sign Out" url=url %}
diff --git a/shynet/dashboard/templates/dashboard/pages/api_settings.html b/shynet/dashboard/templates/dashboard/pages/api_settings.html
new file mode 100644
index 0000000..fed6882
--- /dev/null
+++ b/shynet/dashboard/templates/dashboard/pages/api_settings.html
@@ -0,0 +1,22 @@
+{% extends "base.html" %}
+
+{% block content %}
+ TokenAPI
+
API Token
+ + {{request.user.api_token}} + +