Добавлено сохранение/восстановление токенов
This commit is contained in:
@@ -13,13 +13,13 @@ from drf_yasg import openapi
|
||||
from .api import router
|
||||
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="ToDo List",
|
||||
default_version='v1',
|
||||
description="Swagger Interface for ToDo List",
|
||||
),
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
openapi.Info(
|
||||
title="ToDo List",
|
||||
default_version="v1",
|
||||
description="Swagger Interface for ToDo List",
|
||||
),
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
@@ -28,5 +28,5 @@ urlpatterns = [
|
||||
path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
|
||||
path("api/", include(router.urls)),
|
||||
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
|
||||
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
||||
path("swagger/", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui"),
|
||||
]
|
||||
|
||||
@@ -18,7 +18,8 @@ API_LISTS_UPDATE = "api/lists/{0}/"
|
||||
API_LISTS_PARTIAL_UPDATE = "api/lists/{0}/"
|
||||
API_LISTS_DELETE = "api/lists/{0}/"
|
||||
|
||||
API_TOKEN = "api/token/"
|
||||
API_TOKEN_CREATE = "api/token/"
|
||||
API_TOKEN_REFRESH = "api/token/refresh/"
|
||||
|
||||
|
||||
class UserApi(object):
|
||||
@@ -61,11 +62,23 @@ class UserApi(object):
|
||||
|
||||
"""
|
||||
token = UserApi._raise_or_return_(
|
||||
requests.post(url=self.get_api(API_TOKEN), json={"username": user, "password": passwd})
|
||||
requests.post(
|
||||
url=self.get_api(API_TOKEN_CREATE), json={"username": user, "password": passwd}
|
||||
)
|
||||
)
|
||||
self.token = SimpleNamespace(**token)
|
||||
return self.token
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
Refresh existing token
|
||||
"""
|
||||
token = UserApi._raise_or_return_(
|
||||
requests.post(url=self.get_api(API_TOKEN_REFRESH), json={"refresh": self.token.refresh})
|
||||
)
|
||||
self.token.access = token["access"]
|
||||
return self.token
|
||||
|
||||
def lists_list(self, **argv):
|
||||
"""
|
||||
List all the exsiting to-do lists.
|
||||
|
||||
@@ -13,6 +13,7 @@ DEFAULT_URL = "http://127.0.0.1:8000"
|
||||
|
||||
user = User(url=DEFAULT_URL)
|
||||
user.auth("root", "root")
|
||||
user.refresh()
|
||||
|
||||
# Fetch existing lists:
|
||||
print_lists(user.fetchUserLists())
|
||||
|
||||
@@ -38,6 +38,13 @@ class LoginFrame(tk.Frame):
|
||||
print(ex)
|
||||
message.invalid_login()
|
||||
|
||||
# Если захочется реализовать в логине
|
||||
"""
|
||||
@property
|
||||
def remember(self):
|
||||
return self.rbtn_var.get()
|
||||
"""
|
||||
|
||||
def initAUTH(self) -> None:
|
||||
"""
|
||||
Создает окно авторизации программы
|
||||
@@ -66,3 +73,16 @@ class LoginFrame(tk.Frame):
|
||||
# Кнопка авториазции
|
||||
btn = tk.Button(self, text="Войти", command=self.login_clicked)
|
||||
btn.grid(row=14, column=12, columnspan=3, rowspan=1, sticky="nsew")
|
||||
|
||||
# Если захочется реализовать в логине
|
||||
"""
|
||||
# Запомнить пользователя
|
||||
self.rbtn_var = tk.IntVar(value=0)
|
||||
rbtn = tk.Checkbutton(
|
||||
self,
|
||||
text="Запомнить меня",
|
||||
variable=self.rbtn_var,
|
||||
command=None
|
||||
)
|
||||
rbtn.grid(row=15, column=12, columnspan=3, rowspan=1, sticky="nsew")
|
||||
"""
|
||||
|
||||
@@ -4,6 +4,7 @@ import sys
|
||||
import tkinter as tk
|
||||
from login import LoginFrame
|
||||
from workspace import WorkSpaceFrame
|
||||
from user import User
|
||||
|
||||
if "win" in sys.platform.lower():
|
||||
DEFAULT_URL = "http://localhost:8000"
|
||||
@@ -24,11 +25,19 @@ class Application(tk.Tk):
|
||||
|
||||
def login(self):
|
||||
"""Возвращает пользователя - его можно потом сериализовать"""
|
||||
# Пользователь сохранен! Авторизация не нужна!
|
||||
user = User.load()
|
||||
if user is not None:
|
||||
return user
|
||||
# Не удалось - нужен логин
|
||||
self.frame = LoginFrame(master=self, url=DEFAULT_URL)
|
||||
while not self.frame.loggedIn:
|
||||
self.update_idletasks()
|
||||
self.update()
|
||||
self.frame.destroy()
|
||||
# Нужно запомнить пользователя
|
||||
# if self.frame.remember:
|
||||
# self.frame.user.save()
|
||||
return self.frame.user
|
||||
|
||||
def main(self, user):
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
from datetime import datetime
|
||||
from types import SimpleNamespace
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import json
|
||||
|
||||
from api import UserApi
|
||||
|
||||
@@ -12,6 +15,8 @@ UPDATE_ERROR = "Failed to update property: {0}"
|
||||
|
||||
DATETIME_STR = "%Y-%m-%dT%H:%M:%S.%fZ"
|
||||
|
||||
USER_TOKEN_PATH = os.path.join(Path.home(), ".todo_config.json")
|
||||
|
||||
|
||||
def bad_arguments(x, d):
|
||||
return list((set(x) - set(d)))
|
||||
@@ -150,7 +155,43 @@ class User(UserApi):
|
||||
"""
|
||||
if "DEBUG" in os.environ:
|
||||
return
|
||||
UserApi.auth(self, user, passwd)
|
||||
return UserApi.auth(self, user, passwd)
|
||||
|
||||
def remove(self):
|
||||
"""
|
||||
Remove the login file from homedir
|
||||
"""
|
||||
if not os.path.exists(USER_TOKEN_PATH):
|
||||
return
|
||||
try:
|
||||
os.remove(USER_TOKEN_PATH)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Failed to remove tokens:", e)
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Store user token in homedir
|
||||
"""
|
||||
try:
|
||||
with open(USER_TOKEN_PATH, "w") as handler:
|
||||
json.dump(self.token.__dict__, handler)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Failed to store tokens:", e)
|
||||
|
||||
@staticmethod
|
||||
def load():
|
||||
"""
|
||||
Restore user token from the file in homedir
|
||||
"""
|
||||
if os.path.exists(USER_TOKEN_PATH):
|
||||
try:
|
||||
with open(USER_TOKEN_PATH, "r") as handler:
|
||||
user = User(token=SimpleNamespace(**json.load(handler)))
|
||||
user.refresh()
|
||||
return user
|
||||
except Exception as e:
|
||||
raise RuntimeError("Failed to restore tokens:", e)
|
||||
return None
|
||||
|
||||
# Storing lists - mostly for debug purposes
|
||||
lists_ = make_debug_lists()
|
||||
|
||||
@@ -118,8 +118,20 @@ class WorkSpaceFrame(tk.Frame):
|
||||
self.pack(fill=tk.BOTH, expand=1)
|
||||
self.initLayout(user)
|
||||
|
||||
def destroy(self):
|
||||
tk.Tk.destroy(self)
|
||||
if self.rbtn_var.get() > 0:
|
||||
self.user.save()
|
||||
else:
|
||||
self.user.remove()
|
||||
|
||||
def initLayout(self, user):
|
||||
|
||||
# Запомнить пользователя
|
||||
self.rbtn_var = tk.IntVar(value=1)
|
||||
rbtn = tk.Checkbutton(self, text="Запомнить меня", variable=self.rbtn_var, command=None)
|
||||
rbtn.pack(anchor="n")
|
||||
|
||||
# data
|
||||
self.lists = user.fetchUserLists()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user