Browse Source

Merge branch 'master' of http://git.choozmo.com:3000/zooey/ntcri

Mia Cheng 1 year ago
parent
commit
422bd0ffb0
2 changed files with 67 additions and 26 deletions
  1. 63 12
      app/api/users.py
  2. 4 14
      app/models/models.py

+ 63 - 12
app/api/users.py

@@ -39,7 +39,7 @@ async def query_user(user_id: str):
     :param user_id: E-Mail of the user
     :return: None or the user object
     """
-    result = await User.filter(email=user_id,is_gmail=0).first()
+    result = await User.filter(email=user_id,is_active=1).first()
 
     if not result:
         print('無此筆資料')
@@ -63,7 +63,7 @@ async def query_user_username(user_id: str):
 
 
 @users.post("/login")
-async def login(data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(deps.get_db)):
+async def login(data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(deps.get_db), position: str=Form(default='')):
 
     email = data.username
     password = data.password
@@ -95,7 +95,7 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="https://oauth2.googleapis.com/tok
 
 CLIENT_ID = settings.CLIENT_ID
 @users.post("/login/google/access-token")
-async def login(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default='')
+async def login(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), position: str = Form(default=''),
     ) -> Any:
     """
     OAuth2 compatible token login, get an access token for future requests
@@ -103,12 +103,13 @@ async def login(username: str = Form(default=''), password: str = Form(default='
     access_token = manager.create_access_token(
         data={'sub': username}
     )
-    user = await User.filter(email=email,is_gmail=1).first() # 確認信箱是否已存在
+    user = await User.filter(email=email).first() # 確認信箱是否已存在
     if not user:
-        u = await User.create(username=username, password=password, email=email, is_gmail=1,token=access_token)
+        u = await User.create(username=username, password=password, email=email,token=access_token, is_superuser=0,points=0)
+        create_user = u
     # if user:
     #     print('已用相同信箱註冊過,再開一個GMAIL帳號')
-    #     u = await User.create(username=username, password=password,email=email,is_gmail=1)
+    #     u = await User.create(username=username, password=password,email=email)
     user_pydantic = UserPydantic.from_orm(user)
     user_dict = user_pydantic.dict(exclude_unset=True)
     user_dict.update({"token": access_token})
@@ -118,7 +119,7 @@ async def login(username: str = Form(default=''), password: str = Form(default='
     return_msg = {
         "access_token": access_token,
         "token_type": "bearer",
-        "domain":"ntcri.org",
+        'code':'200',
     }
     return return_msg
     # if add_time_code:
@@ -142,31 +143,70 @@ async def logout():
 
     return {"msg":"logout success","code":200}
 
-@users.post("/add")
-async def add(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), re_password: str = Form(default='')):
+@users.post("/add") # 寄認證信
+async def add(username: str = Form(default=''), password: str = Form(default=''), email: str = Form(default=''), re_password: str = Form(default=''), position: str = Form(default='')):
     if username and password and email:
         user_email = await query_user(email)
         user_username = await query_user_username(username)
+
         if user_email and user_username:
             return {"msg":"該信箱或使用者名稱已存在","code":403}
         # elif user_username:
         #     return {"msg":"該使用者名稱已存在","code":403}
         else:
             if password == re_password:
+                # access_token = manager.create_access_token(
+                #     data={'sub': email}
+                # )
+                print('前',settings.SECRET_KEY)
+                access_token = jwt.encode({'email':email}, settings.SECRET_KEY, algorithm="HS256")
                 hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
-                u = await User.create(username=username, password=hashed_password, email=email,is_superuser=0,is_gmail=0,token='',points=0)
+                u = await User.create(username=username, password=hashed_password, email=email,is_superuser=0,token='',points=0,is_active=0)
                 if u:
-                    message = '註冊成功'
+                    # message = '註冊認證'
+                    message = f"請點擊以下連結完成註冊流程:\n\nhttp://127.0.0.1:8000/api/verify?token={access_token}"
                     subject = '註冊信'
                     print(message)
-                    send_email(email,message,subject)
+                    send_email(email,access_token,subject,message)
+
                     return {"msg": "已寄送註冊信", "code": 200}
+                else:
+                    return {"msg": "未寄出註冊信", "code":403}
             else:
                 return {"msg":"確認密碼錯誤","code":403}
 
     return {"msg": "create user failed", "code": 403}
 
 
+@users.get("/verify") # 註冊認證確認
+async def verify_email(token:str):
+    try:
+        print(token)
+        print('後',settings.SECRET_KEY)
+        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
+        print('解密結果',payload)
+        email = payload["email"]
+        # is_active True
+        user = await User.filter(email=email,is_active=0).first()
+        if user:
+            user_pydantic = UserPydantic.from_orm(user)
+            user_dict = user_pydantic.dict(exclude_unset=True)
+            user_dict.update({"is_active": 1})
+            is_active_update = user.update_from_dict(user_dict)
+            await user.save()
+            result = '信箱驗證成功'
+        else:
+            result = '信箱驗證失敗'
+
+        return {"message": result}
+    except:
+        raise  HTTPException(status_code=400)
+    # except jwt.ExpiredSignatureError:
+    #     raise HTTPException(status_code=400, detail="token已失效")
+    # except jwt.DecodeError:
+    #     raise HTTPException(status_code=400, detail="無效token")
+
+
 def generate_password_reset_token(email: str) -> str:
     delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS)
     now = datetime.utcnow()
@@ -188,10 +228,17 @@ def verify_password_reset_token(token: str):
 
 def send_email(
     email_to: str,
+    token: str,
     subject_template: str = "",
     html_template: str = "",
     environment: Dict[str, Any] = {},
 ):
+    # message = emails.Message(
+    #     subject=JinjaTemplate(subject_template),
+    #     html=JinjaTemplate(html_template),
+    #     mail_from=(settings.EMAILS_FROM_NAME, settings.EMAILS_FROM_EMAIL),
+    # )
+
     message = emails.Message(
         subject=JinjaTemplate(subject_template),
         html=JinjaTemplate(html_template),
@@ -231,6 +278,10 @@ def send_email(
     #     print('測試失敗')
 
 
+def create_singup_url():
+    url=''
+    return url
+
 def send_reset_password_email(email_to: str, email: str, token: str) -> None:
     subject = f"Password recovery for user {email}"
     with open(Path(settings.EMAIL_TEMPLATES_DIR) / "reset_password.html") as f:

+ 4 - 14
app/models/models.py

@@ -13,8 +13,9 @@ class User(Model):
     email = fields.CharField(max_length=128, description="信箱")
     points = fields.IntField(description="點數")
     is_superuser = fields.IntField(description="超級使用者")
-    is_gmail = fields.IntField(description="是否使用gmail登入")
     token = fields.CharField(max_length=200)
+    # position = fields.CharField(max_length=200,description="登入身分")
+    is_active = fields.IntField(description="是否已認證")
 
 class UserPydantic(BaseModel):
     id: int
@@ -23,20 +24,9 @@ class UserPydantic(BaseModel):
     email: str
     points: int
     is_superuser: int
-    is_gmail: int
-    token: str
-    class Config:
-        orm_mode = True
-
-class UserPydantic(BaseModel):
-    id: int
-    username: str
-    password: str
-    email: str
-    points: int
-    is_superuser: int
-    is_gmail: int
     token: str
+    # position : str
+    is_active: int
     class Config:
         orm_mode = True
 #學校