mirror of
https://github.com/devproje/balance-application.git
synced 2024-10-20 15:11:21 +00:00
feat: add login
This commit is contained in:
parent
4220b7f8e0
commit
6672cf7b51
4 changed files with 141 additions and 20 deletions
|
@ -1,9 +1,24 @@
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter, Response
|
||||||
from service.auth_service import Credential
|
from util.auth_lib import hash, gen_token
|
||||||
|
from service.auth_service import Credential, AuthService
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.post("/auth/login")
|
@router.post("/auth/login")
|
||||||
def login(auth: Credential):
|
def login(auth: Credential, resp: Response):
|
||||||
|
service = AuthService()
|
||||||
|
data = service.read(auth.username)
|
||||||
|
|
||||||
return {"ok": 1, "token": "Basic {}"}
|
hashed = hash(auth.password, data.salt)
|
||||||
|
if not data.username == auth.username and not data.password == hashed:
|
||||||
|
resp.status_code = 401
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "Unauthorized"
|
||||||
|
}
|
||||||
|
|
||||||
|
token = gen_token(auth.username, hashed)
|
||||||
|
return {
|
||||||
|
"ok": 1,
|
||||||
|
"token": "Basic {}".format(token)
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from fastapi import APIRouter, Response
|
from fastapi import APIRouter, Response, Request
|
||||||
|
from service.auth_service import AuthService
|
||||||
from service.balance_service import Balance, BalanceService, UpdateForm
|
from service.balance_service import Balance, BalanceService, UpdateForm
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@router.post("/balance", status_code=201)
|
@router.post("/balance", status_code=201)
|
||||||
def insert(balance: Balance, resp: Response):
|
def insert(balance: Balance, req: Request, resp: Response):
|
||||||
started = datetime.now().microsecond / 1000
|
started = datetime.now().microsecond / 1000
|
||||||
|
auth = AuthService()
|
||||||
|
|
||||||
|
if not auth.check_auth(req):
|
||||||
|
resp.status_code = 403
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "permission denied"
|
||||||
|
}
|
||||||
|
|
||||||
|
info = auth.get_data(req)
|
||||||
|
|
||||||
service = BalanceService()
|
service = BalanceService()
|
||||||
ok = service.create(balance=balance)
|
ok = service.create(info["username"], balance=balance)
|
||||||
if not ok == 1:
|
if not ok == 1:
|
||||||
resp.status_code = 500
|
resp.status_code = 500
|
||||||
return {
|
return {
|
||||||
|
@ -23,9 +35,44 @@ def insert(balance: Balance, resp: Response):
|
||||||
"respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started))
|
"respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started))
|
||||||
}
|
}
|
||||||
|
|
||||||
@router.get("/balance/{id}")
|
@router.get("/balance")
|
||||||
def query(id, resp: Response):
|
def query(req: Request, resp: Response):
|
||||||
started = datetime.now().microsecond / 1000
|
started = datetime.now().microsecond / 1000
|
||||||
|
auth = AuthService()
|
||||||
|
if not auth.check_auth(req):
|
||||||
|
resp.status_code = 403
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "permission denied"
|
||||||
|
}
|
||||||
|
|
||||||
|
service = BalanceService()
|
||||||
|
data = service.query()
|
||||||
|
if data == None:
|
||||||
|
resp.status_code = 204
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "no content"
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"ok": 1,
|
||||||
|
"data": data,
|
||||||
|
"respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started))
|
||||||
|
}
|
||||||
|
|
||||||
|
@router.get("/balance/{id}")
|
||||||
|
def find(id, req: Request, resp: Response):
|
||||||
|
started = datetime.now().microsecond / 1000
|
||||||
|
auth = AuthService()
|
||||||
|
|
||||||
|
if not auth.check_auth(req):
|
||||||
|
resp.status_code = 403
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "permission denied"
|
||||||
|
}
|
||||||
|
|
||||||
service = BalanceService()
|
service = BalanceService()
|
||||||
data = service.read(int(id))
|
data = service.read(int(id))
|
||||||
|
|
||||||
|
@ -41,7 +88,18 @@ def query(id, resp: Response):
|
||||||
}
|
}
|
||||||
|
|
||||||
@router.patch("/balance/{action}/{id}")
|
@router.patch("/balance/{action}/{id}")
|
||||||
def update(action, id, balance: UpdateForm, resp: Response):
|
def update(action, id, balance: UpdateForm, req: Request, resp: Response):
|
||||||
|
started = datetime.now().microsecond / 1000
|
||||||
|
auth = AuthService()
|
||||||
|
|
||||||
|
print(auth.check_auth(req))
|
||||||
|
if not auth.check_auth(req):
|
||||||
|
resp.status_code = 403
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "permission denied"
|
||||||
|
}
|
||||||
|
|
||||||
service = BalanceService()
|
service = BalanceService()
|
||||||
if action != "name" and action != "date" and action != "price" and action != "buy" and action != "memo":
|
if action != "name" and action != "date" and action != "price" and action != "buy" and action != "memo":
|
||||||
print(action)
|
print(action)
|
||||||
|
@ -91,12 +149,22 @@ def update(action, id, balance: UpdateForm, resp: Response):
|
||||||
return {
|
return {
|
||||||
"ok": 1,
|
"ok": 1,
|
||||||
"id": int(id),
|
"id": int(id),
|
||||||
"action": action
|
"action": action,
|
||||||
|
"respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started))
|
||||||
}
|
}
|
||||||
|
|
||||||
@router.delete("/balance/{id}")
|
@router.delete("/balance/{id}")
|
||||||
def delete(id, resp: Response):
|
def delete(id, req: Request, resp: Response):
|
||||||
started = datetime.now().microsecond / 1000
|
started = datetime.now().microsecond / 1000
|
||||||
|
auth = AuthService()
|
||||||
|
|
||||||
|
if not auth.check_auth(req):
|
||||||
|
resp.status_code = 403
|
||||||
|
return {
|
||||||
|
"ok": 0,
|
||||||
|
"errno": "permission denied"
|
||||||
|
}
|
||||||
|
|
||||||
service = BalanceService()
|
service = BalanceService()
|
||||||
ok = service.delete(int(id))
|
ok = service.delete(int(id))
|
||||||
if not ok == 1:
|
if not ok == 1:
|
||||||
|
|
|
@ -44,7 +44,7 @@ class AuthService:
|
||||||
|
|
||||||
def read(self, username: str):
|
def read(self, username: str):
|
||||||
cur = self._conn.cursor()
|
cur = self._conn.cursor()
|
||||||
cur.execute("select * from account where username = %s;", (username))
|
cur.execute("select * from account where username = %s;", (username, ))
|
||||||
data = cur.fetchone()
|
data = cur.fetchone()
|
||||||
if data == None:
|
if data == None:
|
||||||
return None
|
return None
|
||||||
|
@ -58,16 +58,32 @@ class AuthService:
|
||||||
password = data[2],
|
password = data[2],
|
||||||
salt = data[3]
|
salt = data[3]
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_auth(self, req: Request) -> bool:
|
def get_data(self, req: Request):
|
||||||
raw = req.headers.get("Authorization")
|
raw = req.headers.get("Authorization")
|
||||||
|
if raw == None:
|
||||||
|
return None
|
||||||
|
|
||||||
raw_token = raw.removeprefix("Basic ").encode("ascii")
|
raw_token = raw.removeprefix("Basic ").encode("ascii")
|
||||||
|
|
||||||
token = base64.b64decode(raw_token)
|
token = base64.b64decode(raw_token)
|
||||||
data = token.decode("utf-8").split(":")
|
data = token.decode("utf-8").split(":")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"username": data[0],
|
||||||
|
"password": data[1]
|
||||||
|
}
|
||||||
|
|
||||||
acc = self.read(data[0])
|
def check_auth(self, req: Request) -> bool:
|
||||||
if acc.username == data[0] and acc.password == data[1]:
|
data = self.get_data(req)
|
||||||
|
if data == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
acc = self.read(data["username"])
|
||||||
|
if acc == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if acc.username == data["username"] and acc.password == data["password"]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -20,13 +20,13 @@ class BalanceService:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._conn = psycopg2.connect(conn_param)
|
self._conn = psycopg2.connect(conn_param)
|
||||||
|
|
||||||
def create(self, balance: Balance):
|
def create(self, username: str, balance: Balance):
|
||||||
ok = True
|
ok = True
|
||||||
cur = self._conn.cursor()
|
cur = self._conn.cursor()
|
||||||
try:
|
try:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"insert into balset(name, date, price, buy, memo) values (%s, %s, %s, %s, %s);",
|
"insert into balset(name, uid, date, price, buy, memo) values (%s, %s, %s, %s, %s, %s);",
|
||||||
(balance.name, balance.date, balance.price, balance.buy, balance.memo)
|
(balance.name, username, balance.date, balance.price, balance.buy, balance.memo)
|
||||||
)
|
)
|
||||||
|
|
||||||
self._conn.commit()
|
self._conn.commit()
|
||||||
|
@ -39,6 +39,28 @@ class BalanceService:
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
|
def query(self):
|
||||||
|
cur = self._conn.cursor()
|
||||||
|
cur.execute("select * from balset;")
|
||||||
|
|
||||||
|
raw = cur.fetchall()
|
||||||
|
data = []
|
||||||
|
|
||||||
|
if len(raw) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for d in raw:
|
||||||
|
data.append({
|
||||||
|
"id": d[0],
|
||||||
|
"name": d[1],
|
||||||
|
"date": d[2],
|
||||||
|
"price": d[3],
|
||||||
|
"buy": d[4],
|
||||||
|
"memo": d[5]
|
||||||
|
})
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
def read(self, id: int):
|
def read(self, id: int):
|
||||||
cur = self._conn.cursor()
|
cur = self._conn.cursor()
|
||||||
cur.execute("select * from balset where id = %s;", (id))
|
cur.execute("select * from balset where id = %s;", (id))
|
||||||
|
|
Loading…
Reference in a new issue