From 4b7540b7c4fa7cb7fe12967f1cb28517ee729503 Mon Sep 17 00:00:00 2001 From: kooqooo Date: Fri, 26 Apr 2024 21:48:13 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B0=9C=EC=9D=B8=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=8F=99=EC=9D=98=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 테스트가 필요합니다. #36 --- .gitignore | 3 ++ app.py | 56 ++------------------ back/managers/account_models.py | 4 +- back/users.py | 17 ++++++- pages/1_home.py | 90 ++++++++++++++++++--------------- pages/1_privacy_policy.py | 88 ++++++++++++++++++++++++++++++++ privacy_policy.txt | 14 +++++ 7 files changed, 176 insertions(+), 96 deletions(-) create mode 100644 pages/1_privacy_policy.py create mode 100644 privacy_policy.txt diff --git a/.gitignore b/.gitignore index 03d5d94..f3d256e 100644 --- a/.gitignore +++ b/.gitignore @@ -212,3 +212,6 @@ WiredTiger* # package exception !requirements.txt + +# privacy policy +!privacy_policy.txt \ No newline at end of file diff --git a/app.py b/app.py index 776d80d..816be10 100644 --- a/app.py +++ b/app.py @@ -99,61 +99,13 @@ unsafe_allow_html=True, ) -# 개인정보 처리방침 내용 -privacy_policy = """ -「개인정보 보호법」 제15조 및 제22조에 따라 아래와 같은 내용으로 본인의 개인정보를 수집‧이용하는데 동의합니다. - - - -• 수집∙이용 목적 - -: 개발자 모의면접 서비스 제공을 위한 유저 식별, 예상 질문 생성, 모의면접 진행 등의 서비스에 이용 - -• 수집ㆍ이용할 개인정보의 내용 - -: 이름, 이메일, 이력서 - -• 보유 및 이용 기간 - -: 수집‧이용 동의일로부터 6개월 이내 - -※ 귀하는 이에 동의를 거부할 수 있습니다. - -다만 동의가 없을 경우 본 서비스 사용이 불가합니다.""" - -# 스트림릿으로 개인정보 처리방침 내용을 보여줌 -st.text_area("개인정보 처리방침", privacy_policy, height=300) - -# 동의 여부를 라디오 버튼으로 선택 -consent = st.radio("위 개인정보 처리방침에 동의하십니까?", ('동의', '동의하지 않음')) -st.session_state.agreement = consent - - - - -# # 사용자가 선택한 값에 따라 다르게 행동 -# if st.button("제출"): -# if consent == '동의': -# st.success("이용 약관에 동의하셨습니다. 감사합니다!") -# else: -# st.error("이용 약관에 동의하지 않으셨습니다. 동의가 필요합니다.") - -check_list = st.session_state.agreement if st.button("LOGIN(KAKAO)"): - if check_list != '동의': - st.error("동의하지 않으셨습니다. 동의가 필요합니다.") - else: - st.session_state["cur_user"] = "kakao" # 사용자 상태 설정 - goto_login_page() - - + st.session_state["cur_user"] = "kakao" # 사용자 상태 설정 + goto_login_page() # 비회원 버튼 if st.button("GUEST"): - if check_list != '동의': - st.error("동의하지 않으셨습니다. 동의가 필요합니다.") - else: - st.session_state["cur_user"] = "guest" # 사용자 상태 설정 - switch_page("home") + st.session_state["cur_user"] = "guest" # 사용자 상태 설정 + switch_page("privacy_policy") diff --git a/back/managers/account_models.py b/back/managers/account_models.py index 97fe120..aa97cd7 100644 --- a/back/managers/account_models.py +++ b/back/managers/account_models.py @@ -17,5 +17,5 @@ class User(BaseModel): expires_at: Optional[int] = None # 언제 사용할까요? # 아직 사용하지 않음 joined_at: Optional[int] = None # 가입 날짜 last_login: Optional[int] = None # 마지막 로그인 시간 - records: Optional[List[Record]] = [] # 사용자의 이력 - available_credits: Optional[int] = 3 # 무료로 사용 가능한 크레딧 # 사용하지 않음 \ No newline at end of file + is_privacy_policy_agreed: Optional[bool] = False # 개인정보 처리방침 동의 여부 + records: Optional[List[Record]] = [] # 사용자의 이력 \ No newline at end of file diff --git a/back/users.py b/back/users.py index ec8e0ac..7443735 100644 --- a/back/users.py +++ b/back/users.py @@ -24,7 +24,22 @@ # print("This email already exists") # 이미 존재하는 이메일인 경우 출력 # await collection.create_index([("email", ASCENDING)], unique=True) - + +@router.get("/{email}/privacy_policy") +async def is_privacy_policy(email: str) -> bool: + """ + 사용자의 개인정보 처리방침 동의 여부를 반환하는 함수입니다. + + Parameters: + email (str): 사용자 이메일 + + Returns: + bool: 개인정보 처리방침에 동의한 경우 True를 반환하고, 그렇지 않은 경우 False를 반환합니다. + """ + user = collection.find_one({"_id": email}, {"is_privacy_policy_agreed": 1}) + if user: + return user.get("is_privacy_policy_agreed", False) + raise HTTPException(status_code=404, detail="User not found") @router.get("/{email}/exists") async def check_email_exists(email: str): diff --git a/pages/1_home.py b/pages/1_home.py index 7e1cefb..132ec82 100644 --- a/pages/1_home.py +++ b/pages/1_home.py @@ -18,9 +18,8 @@ from back.user_authorization import verify_token from back.managers.account_models import User, Record -NEXT_PAGE = "user" -is_logged_in = False -last_login = 0 +NEXT_PAGE = "privacy_policy" +st.session_state.is_logged_in = False if "logger" not in st.session_state: # logru_logger(**config.config) @@ -41,10 +40,10 @@ st.session_state["access_token"] = token # 토큰 검증, 토큰 페이로드 디코딩 - is_logged_in, token_payload = verify_token(st.session_state["user_id"]) + st.session_state.is_logged_in, st.session_state.token_payload = verify_token(st.session_state["user_id"]) # 로그인 상태에 따라 사용자 정보 설정 -if "user_id" in st.session_state and is_logged_in: +if "user_id" in st.session_state and st.session_state.is_logged_in: user_info = get_info_from_kakao(st.session_state["access_token"]) else: user_info = {"properties": {"nickname": "GUEST"}, "kakao_account": {"email": "GUEST"}, "access_token": "GUEST"} @@ -66,39 +65,6 @@ st.session_state["user_id"] = user_info["kakao_account"]["email"] print("user_id : ", st.session_state["user_id"]) -print("is_logged_in : ", is_logged_in) -if is_logged_in: - # DB에 저장할 변수 설정 - last_login = token_payload["auth_time"] - expires_at = token_payload["exp"] - - user = User( - _id=st.session_state["user_email"], - name=st.session_state["nickname"], - access_token=st.session_state["access_token"], - id_token=st.session_state["user_id"], - last_login=last_login, - expires_at=expires_at, - ) - -if not is_logged_in: - user = User( - _id="GUEST", - name="GUEST", - access_token="GUEST", - id_token="GUEST", - ) - -is_member = requests.get(f"http://localhost:{PORT}/users/{st.session_state['user_email']}/exists").json() - -if is_member: # 이미 DB에 저장된 사용자라면 - user = requests.put(f"http://localhost:{PORT}/users/{st.session_state['user_email']}",json=user.model_dump(by_alias=True)).json() - -elif not is_member: # DB에 저장된 사용자가 아니라면 - user.joined_at = last_login - user = requests.post(f"http://localhost:{PORT}/users/",json=user.model_dump(by_alias=True)).json() - - if "openai_api_key" not in st.session_state: os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY st.session_state.openai_api_key = OPENAI_API_KEY @@ -124,10 +90,52 @@ if "USER_ICON" not in st.session_state: st.session_state["USER_ICON"] = Image.open(os.path.join(IMG_PATH, "user_icon.png")) -if "user_name" not in st.session_state: - st.session_state["user_name"] = "아무개" - if "temperature" not in st.session_state: st.session_state["temperature"] = 0 +if "is_privacy_policy_agreed" not in st.session_state: + st.session_state["is_privacy_policy_agreed"] = False + +if "last_login" not in st.session_state: + st.session_state["last_login"] = None + +if "expires_at" not in st.session_state: + st.session_state["expires_at"] = None + +print("is_logged_in : ", st.session_state.is_logged_in) +if st.session_state.is_logged_in: + # DB에 저장할 변수 설정 + st.session_state.last_login = st.session_state.token_payload["auth_time"] + st.session_state.expires_at = st.session_state.token_payload["exp"] + + user = User( + _id=st.session_state["user_email"], + name=st.session_state["nickname"], + access_token=st.session_state["access_token"], + id_token=st.session_state["user_id"], + last_login=st.session_state.last_login, + expires_at=st.session_state.expires_at, + ) + +if not st.session_state.is_logged_in: + user = User( + _id="GUEST", + name="GUEST", + access_token="GUEST", + id_token="GUEST", + ) + +st.session_state.is_member = requests.get(f"http://localhost:{PORT}/users/{st.session_state['user_email']}/exists").json() + +if not st.session_state.is_member: # DB에 저장된 사용자가 아니라면 DB에 저장 + user.joined_at = st.session_state.last_login + user = requests.post(f"http://localhost:{PORT}/users/",json=user.model_dump(by_alias=True)).json() + +elif st.session_state.is_member: # 이미 DB에 저장된 사용자라면 개인 정보 동의 여부 확인 + st.session_state.is_privacy_policy_agreed = requests.get(f"http://localhost:{PORT}/users/{st.session_state['user_email']}/privacy_policy").json() + user = requests.put(f"http://localhost:{PORT}/users/{st.session_state['user_email']}",json=user.model_dump(by_alias=True)).json() + +if st.session_state.is_privacy_policy_agreed: # 개인 정보 동의를 했다면 다음 페이지로 넘어가기 + NEXT_PAGE = "user" + switch_page(NEXT_PAGE) diff --git a/pages/1_privacy_policy.py b/pages/1_privacy_policy.py new file mode 100644 index 0000000..ee0afb2 --- /dev/null +++ b/pages/1_privacy_policy.py @@ -0,0 +1,88 @@ +import os +import sys +import requests + +import streamlit as st +from PIL import Image +from streamlit_extras.switch_page_button import switch_page + +sys.path.append("./") +sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__)))) + +from config import IMG_PATH, path, PORT +from src.util import read_prompt_from_txt, local_css +from back.managers.account_models import User, Record + +st.session_state['FAV_IMAGE_PATH'] = os.path.join(IMG_PATH, "favicon.png") + +st.set_page_config( + page_title="Hello Jobits", # 브라우저탭에 뜰 제목 + page_icon=Image.open(st.session_state.FAV_IMAGE_PATH), # 브라우저 탭에 뜰 아이콘 + layout="wide", + initial_sidebar_state="collapsed", +) + +NEXT_PAGE = "user" + +#### style css #### +MAIN_IMG = st.session_state.MAIN_IMG +LOGO_IMG = st.session_state.LOGO_IMG + +st.title("안녕하세요, " + st.session_state.nickname + "님!") # 사용자 이름을 받아서 화면에 출력합니다. + +local_css(os.path.join(path, "front", "css", "background.css")) + +privacy_policy = """ +개인정보 보호법」제15조 및 제22조에 따라 아래와 같은 내용으로 본인의 개인정보를 수집‧이용하는데 동의합니다. + +• 수집∙이용 목적 + : 개발자 모의면접 서비스 제공을 위한 유저 식별, 예상 질문 생성, 모의면접 진행 등의 서비스에 이용 + +• 수집ㆍ이용할 개인정보의 내용 + : 이름, 이메일, 이력서 + +• 보유 및 이용 기간 + : 수집‧이용 동의일로부터 6개월 이내 + +※ 귀하는 이에 동의를 거부할 수 있습니다. + +다만 동의가 없을 경우 본 서비스 사용이 불가합니다.""" + +st.text_area("개인정보 처리방침", privacy_policy, height=300) + +# 동의 여부를 라디오 버튼으로 선택 +consent = st.radio("위 개인정보 처리방침에 동의하십니까?", ('동의', '동의하지 않음')) +st.session_state.agreement = consent + +if st.session_state.is_logged_in: + # DB에 저장할 변수 설정 + st.session_state.last_login = st.session_state.token_payload["auth_time"] + st.session_state.expires_at = st.session_state.token_payload["exp"] + + user = User( + _id=st.session_state["user_email"], + name=st.session_state["nickname"], + access_token=st.session_state["access_token"], + id_token=st.session_state["user_id"], + last_login=st.session_state.last_login, + expires_at=st.session_state.expires_at, + is_privacy_policy_agreed=True + ) + +if not st.session_state.is_logged_in: + user = User( + _id="GUEST", + name="GUEST", + access_token="GUEST", + id_token="GUEST", + ) + +if consent == '동의': + st.session_state.is_privacy_policy_agreed = True + + if st.session_state.is_logged_in: # 카카오 로그인 사용자인 경우 동의 여부 저장 + user = requests.put(f"http://localhost:{PORT}/users/{st.session_state['user_email']}",json=user.model_dump(by_alias=True)).json() + + switch_page(NEXT_PAGE) +else: + st.error("동의하지 않으셨습니다. 동의가 필요합니다.") \ No newline at end of file diff --git a/privacy_policy.txt b/privacy_policy.txt new file mode 100644 index 0000000..5f32d20 --- /dev/null +++ b/privacy_policy.txt @@ -0,0 +1,14 @@ +「개인정보 보호법」 제15조 및 제22조에 따라 아래와 같은 내용으로 본인의 개인정보를 수집‧이용하는데 동의합니다. + +• 수집∙이용 목적 + : 개발자 모의면접 서비스 제공을 위한 유저 식별, 예상 질문 생성, 모의면접 진행 등의 서비스에 이용 + +• 수집ㆍ이용할 개인정보의 내용 + : 이름, 이메일, 이력서 + +• 보유 및 이용 기간 + : 수집‧이용 동의일로부터 6개월 이내 + +※ 귀하는 이에 동의를 거부할 수 있습니다. + +다만 동의가 없을 경우 본 서비스 사용이 불가합니다. \ No newline at end of file