Добавлено сохранение/восстановление токенов

This commit is contained in:
Ivan
2021-04-27 19:59:31 +03:00
parent 3e307506e9
commit 277f1e1aff
7 changed files with 108 additions and 12 deletions

View File

@@ -15,7 +15,7 @@ from .api import router
schema_view = get_schema_view(
openapi.Info(
title="ToDo List",
default_version='v1',
default_version="v1",
description="Swagger Interface for ToDo List",
),
public=True,
@@ -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"),
]

View File

@@ -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.

View File

@@ -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())

View File

@@ -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")
"""

View File

@@ -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):

View File

@@ -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()

View File

@@ -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()