Merge pull request #1 from devproje/auth

Auth
This commit is contained in:
Project_IO 2024-09-17 15:08:22 +09:00 committed by GitHub
commit 3e87cd3d14
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 91 additions and 135 deletions

View file

@ -39,12 +39,7 @@ DB_USERNAME=user
DB_PASSWORD=sample1234! DB_PASSWORD=sample1234!
``` ```
5. generate.py를 실행하여 테이블 및 계정을 생성 해줍니다. 5. fastapi 명령어를 이용하여 서비스를 실행 해줍니다.
```bash
python generate.py
```
6. fastapi 명령어를 이용하여 서비스를 실행 해줍니다.
```bash ```bash
fastapi run app.py fastapi run app.py
``` ```
@ -52,3 +47,6 @@ fastapi run app.py
```bash ```bash
fastapi run app.py --port 3000 fastapi run app.py --port 3000
``` ```
## License
본 프로젝트는 (MIT License)[https://github.com/devproje/balance-application/blob/master/LICENSE]를 따릅니다.

24
app.py
View file

@ -1,9 +1,29 @@
import psycopg2
from generate import on_load
from fastapi import FastAPI, Response from fastapi import FastAPI, Response
from routes.auth import router as auth from routes.auth import router as auth
from contextlib import asynccontextmanager
from util.config import conn_param, db_url
from routes.balance import router as balance from routes.balance import router as balance
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
app = FastAPI() @asynccontextmanager
async def lifespan(app: FastAPI):
conn = psycopg2.connect(conn_param)
cur = conn.cursor()
try:
print("loading database for: %s" % db_url())
on_load(conn, cur)
except:
print("[warn] error occurred while creating table. aborted")
finally:
cur.close()
conn.close()
yield
app = FastAPI(lifespan=lifespan)
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,
@ -14,7 +34,7 @@ app.add_middleware(
) )
@app.get("/") @app.get("/")
def index(resp: Response): async def index(resp: Response):
resp.headers.setdefault("Content-Type", "text") resp.headers.setdefault("Content-Type", "text")
return "Hello, World!" return "Hello, World!"

View file

@ -1,94 +1,61 @@
import psycopg2
import random, string import random, string
from getpass import getpass from getpass import getpass
from util.auth_lib import hash from util.auth_lib import hash
from util.config import conn_param
from service.auth_service import AuthData, AuthService from service.auth_service import AuthData, AuthService
def gen_salt(length = 20): def gen_salt(length = 20):
letters = string.ascii_lowercase + string.digits + string.punctuation letters = string.ascii_lowercase + string.digits + string.punctuation
return "".join(random.choice(letters) for i in range(length)) return "".join(random.choice(letters) for i in range(length))
def _gen_token(): def _new_account():
deps = string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation name = input("input your display name: ")
token = "".join(random.choice(deps) for i in range(20)) username = input("input your username: ")
password = getpass("input your password: ")
passchk = getpass("type password one more time: ")
salt = gen_salt()
sec = open("./secret_token.txt", "w") if password != passchk:
sec.write(token) return
sec.close()
def __main__():
conn = psycopg2.connect(conn_param)
cur = conn.cursor()
try:
f = open("./load.txt", "r")
_gen_token()
if f.read().split("=")[1] == "false":
raise ValueError("value not true")
print("server already initialized")
f.close()
except:
cur.execute(
"""
create table if not exists account(
name varchar(25),
username varchar(25) not null,
password varchar(100) not null,
salt varchar(50),
primary key(username)
);
"""
)
cur.execute(
"""
create table if not exists balset(
id serial primary key,
uid varchar(25) not null,
name varchar(50),
date bigint,
price bigint,
buy boolean,
memo varchar(300),
constraint FK_Account_ID
foreign key (uid)
references account(username)
on delete CASCADE
);
"""
)
conn.commit()
cur.close()
conn.close()
name = input("input your display name: ")
username = input("input your username: ")
password = getpass("input your password: ")
passchk = getpass("type password one more time: ")
salt = gen_salt()
if password != passchk:
return
hashed_password = hash(password, salt) hashed_password = hash(password, salt)
packed = AuthData( packed = AuthData(
name=name, name=name,
username=username, username=username,
password=hashed_password, password=hashed_password,
salt=salt salt=salt
) )
service = AuthService() service = AuthService()
service.create(data=packed) service.create(data=packed)
f = open("load.txt", "w") def on_load(conn, cur):
f.write("init=true") cur.execute(
"""
f.close() create table account(
name varchar(25),
__main__() username varchar(25) not null,
password varchar(100) not null,
salt varchar(50),
primary key(username)
);
"""
)
cur.execute(
"""
create table balset(
id serial primary key,
uid varchar(25) not null,
name varchar(50),
date bigint,
price bigint,
buy boolean,
memo varchar(300),
constraint FK_Account_ID
foreign key (uid)
references account(username)
on delete CASCADE
);
"""
)
conn.commit()
_new_account()

View file

@ -87,12 +87,10 @@ def find(id, req: Request, resp: Response):
"respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started)) "respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started))
} }
@router.patch("/balance/{action}/{id}") @router.put("/balance/{id}")
def update(action, id, balance: UpdateForm, req: Request, resp: Response): def update(id, balance: UpdateForm, req: Request, resp: Response):
started = datetime.now().microsecond / 1000 started = datetime.now().microsecond / 1000
auth = AuthService() auth = AuthService()
print(auth.check_auth(req))
if not auth.check_auth(req): if not auth.check_auth(req):
resp.status_code = 403 resp.status_code = 403
return { return {
@ -101,43 +99,7 @@ def update(action, id, balance: UpdateForm, req: Request, resp: Response):
} }
service = BalanceService() service = BalanceService()
if action != "name" and action != "date" and action != "price" and action != "buy" and action != "memo": ok = service.update(int(id), balance)
print(action)
print(id)
resp.status_code = 400
return {"ok": 0, "errno": "action must be to name, date, price or memo"}
if action == "name" and balance.name == "":
resp.status_code = 400
return {"ok": 0, "action": action, "errno": "name value cannot be empty"}
if action == "date" and balance.date <= 0:
resp.status_code = 400
return {"ok": 0, "action": action, "errno": "date value cannot be 0 or minus"}
if action == "price" and balance.price <= 0:
resp.status_code = 400
return {"ok": 0, "action": action, "errno": "price value cannot be 0 or minus"}
if action == "memo" and len(balance.memo) > 300:
resp.status_code = 400
return {
"ok": 0,
"action": action,
"errno": "memo value size is too long: (maximum size: 300 bytes, your size: {} bytes)".format(len(balance.memo))
}
ok = service.update(
int(id),
action,
{
"name": balance.name,
"date": balance.date,
"price": balance.price,
"buy": balance.buy,
"memo": balance.memo
}
)
if not ok == 1: if not ok == 1:
resp.status_code = 500 resp.status_code = 500
@ -149,7 +111,6 @@ def update(action, id, balance: UpdateForm, req: Request, resp: Response):
return { return {
"ok": 1, "ok": 1,
"id": int(id), "id": int(id),
"action": action,
"respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started)) "respond_time": "{}ms".format(round((datetime.now().microsecond / 1000) - started))
} }

View file

@ -82,11 +82,18 @@ class BalanceService:
"memo": data[5] "memo": data[5]
} }
def update(self, id: int, act: str, balance: UpdateForm): def update(self, id: int, balance: UpdateForm):
ok = True ok = True
cur = self._conn.cursor() cur = self._conn.cursor()
try: try:
cur.execute(f"update balset set {act} = %s where id = %s;", (balance[act], id)) cur.execute("update balset set name = %s, date = %s, price = %s, buy = %s, memo = %s where id = %s;", (
balance.name,
balance.date,
balance.price,
balance.buy,
balance.memo,
id
))
self._conn.commit() self._conn.commit()
except: except:
self._conn.rollback() self._conn.rollback()
@ -101,7 +108,7 @@ class BalanceService:
ok = True ok = True
cur = self._conn.cursor() cur = self._conn.cursor()
try: try:
cur.execute("delete from balset where id = %s;", (id)) cur.execute("delete from balset where id = %s;", (str(id)))
self._conn.commit() self._conn.commit()
except: except:
self._conn.rollback() self._conn.rollback()

View file

@ -1,7 +1,7 @@
import os import os
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv(verbose=True, override=True)
def _load_secret(): def _load_secret():
try: try:
@ -11,6 +11,9 @@ def _load_secret():
return tok return tok
def db_url():
return os.getenv("DB_URL")
conn_param = "host=%s port=%s dbname=%s user=%s password=%s" % ( conn_param = "host=%s port=%s dbname=%s user=%s password=%s" % (
os.getenv("DB_URL"), os.getenv("DB_URL"),
os.getenv("DB_PORT"), os.getenv("DB_PORT"),