Merge branch 'develop-emp-chg-inst' into feature-NEWDWH2021-1507-download
This commit is contained in:
commit
f897f34672
@ -70,11 +70,22 @@ def login(
|
|||||||
jwt_token = login_service.login(request.username, request.password)
|
jwt_token = login_service.login(request.username, request.password)
|
||||||
except NotAuthorizeException as e:
|
except NotAuthorizeException as e:
|
||||||
logger.info(f'ログイン失敗:{e}')
|
logger.info(f'ログイン失敗:{e}')
|
||||||
|
# ログイン失敗回数をカウント
|
||||||
|
login_service.increase_login_failed_count(request.username)
|
||||||
|
# ログイン失敗回数を超過した場合はメッセージを変える
|
||||||
|
if login_service.is_login_failed_limit_exceeded(request.username):
|
||||||
|
login_service.on_login_fail_limit_exceeded(request.username)
|
||||||
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED)
|
||||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_ERROR)
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_ERROR)
|
||||||
except JWTTokenVerifyException as e:
|
except JWTTokenVerifyException as e:
|
||||||
logger.info(f'ログイン失敗:{e}')
|
logger.info(f'ログイン失敗:{e}')
|
||||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||||
|
|
||||||
|
# ログイン成功問わず、DBのログイン失敗回数が10回以上あれば、ログアウト画面にリダイレクトする
|
||||||
|
if login_service.is_login_failed_limit_exceeded(request.username):
|
||||||
|
logger.info(f'ログイン失敗回数が10回以上: {request.username}')
|
||||||
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED)
|
||||||
|
|
||||||
verified_token = jwt_token.verify_token()
|
verified_token = jwt_token.verify_token()
|
||||||
# 普通の認証だと、`cognito:username`に入る。
|
# 普通の認証だと、`cognito:username`に入る。
|
||||||
user_id = verified_token.user_id
|
user_id = verified_token.user_id
|
||||||
|
|||||||
@ -189,7 +189,7 @@ class DatabaseClient:
|
|||||||
self.__session = None
|
self.__session = None
|
||||||
|
|
||||||
def to_jst(self):
|
def to_jst(self):
|
||||||
self.execute('SET time_zone = "+9:00"')
|
self.execute('SET SESSION time_zone = "Asia/Tokyo"')
|
||||||
|
|
||||||
def __execute_with_transaction(self, query: str, parameters: dict):
|
def __execute_with_transaction(self, query: str, parameters: dict):
|
||||||
# トランザクションを開始してクエリを実行する
|
# トランザクションを開始してクエリを実行する
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from datetime import datetime
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from src.model.db.base_db_model import BaseDBModel
|
from src.model.db.base_db_model import BaseDBModel
|
||||||
|
from src.system_var import constants
|
||||||
|
|
||||||
class UserMasterModel(BaseDBModel):
|
class UserMasterModel(BaseDBModel):
|
||||||
user_id: Optional[str]
|
user_id: Optional[str]
|
||||||
@ -25,6 +25,8 @@ class UserMasterModel(BaseDBModel):
|
|||||||
updater: Optional[str]
|
updater: Optional[str]
|
||||||
update_date: Optional[datetime]
|
update_date: Optional[datetime]
|
||||||
mntuser_flg: Optional[str]
|
mntuser_flg: Optional[str]
|
||||||
|
mntuser_login_failed_cnt: Optional[int]
|
||||||
|
mntuser_last_login_failed_datetime: Optional[datetime]
|
||||||
|
|
||||||
def is_enable_user(self):
|
def is_enable_user(self):
|
||||||
return self.enabled_flg == 'Y'
|
return self.enabled_flg == 'Y'
|
||||||
@ -34,3 +36,6 @@ class UserMasterModel(BaseDBModel):
|
|||||||
|
|
||||||
def is_groupware_user(self):
|
def is_groupware_user(self):
|
||||||
return self.mntuser_flg == '0' or self.mntuser_flg is None
|
return self.mntuser_flg == '0' or self.mntuser_flg is None
|
||||||
|
|
||||||
|
def is_login_failed_limit_exceeded(self):
|
||||||
|
return self.mntuser_login_failed_cnt >= constants.LOGIN_FAIL_LIMIT
|
||||||
@ -6,6 +6,19 @@ logger = get_logger('ユーザー取得')
|
|||||||
|
|
||||||
|
|
||||||
class UserMasterRepository(BaseRepository):
|
class UserMasterRepository(BaseRepository):
|
||||||
|
|
||||||
|
def to_jst(self):
|
||||||
|
self._database.to_jst()
|
||||||
|
|
||||||
|
def begin(self):
|
||||||
|
self._database.begin()
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
self._database.commit()
|
||||||
|
|
||||||
|
def rollback(self):
|
||||||
|
self._database.rollback()
|
||||||
|
|
||||||
FETCH_SQL = """\
|
FETCH_SQL = """\
|
||||||
SELECT
|
SELECT
|
||||||
*
|
*
|
||||||
@ -26,3 +39,46 @@ class UserMasterRepository(BaseRepository):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"DB Error : Exception={e}")
|
logger.exception(f"DB Error : Exception={e}")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def increase_login_failed_count(self, parameter: dict) -> UserMasterModel:
|
||||||
|
try:
|
||||||
|
query = """\
|
||||||
|
UPDATE
|
||||||
|
src05.user_mst
|
||||||
|
SET
|
||||||
|
mntuser_login_failed_cnt =
|
||||||
|
CASE
|
||||||
|
WHEN
|
||||||
|
DATE(mntuser_last_login_failed_datetime) = DATE(CURRENT_TIMESTAMP())
|
||||||
|
THEN
|
||||||
|
mntuser_login_failed_cnt + 1
|
||||||
|
ELSE
|
||||||
|
1
|
||||||
|
END,
|
||||||
|
mntuser_last_login_failed_datetime = CURRENT_TIMESTAMP()
|
||||||
|
WHERE
|
||||||
|
user_id = :user_id
|
||||||
|
AND
|
||||||
|
mntuser_flg = 1;\
|
||||||
|
"""
|
||||||
|
self._database.execute(query, parameter)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"DB Error : Exception={e}")
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def disable_mnt_user(self, parameter: dict) -> UserMasterModel:
|
||||||
|
try:
|
||||||
|
query = """\
|
||||||
|
UPDATE
|
||||||
|
src05.user_mst
|
||||||
|
SET
|
||||||
|
enabled_flg = 'N'
|
||||||
|
WHERE
|
||||||
|
user_id = :user_id
|
||||||
|
AND
|
||||||
|
mntuser_flg = 1\
|
||||||
|
"""
|
||||||
|
self._database.execute(query, parameter)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"DB Error : Exception={e}")
|
||||||
|
raise e
|
||||||
|
|||||||
@ -49,6 +49,27 @@ class LoginService(BaseService):
|
|||||||
user_record: UserMasterModel = self.user_repository.fetch_one({'user_id': user_id})
|
user_record: UserMasterModel = self.user_repository.fetch_one({'user_id': user_id})
|
||||||
return user_record
|
return user_record
|
||||||
|
|
||||||
|
def increase_login_failed_count(self, user_id: str):
|
||||||
|
|
||||||
|
try:
|
||||||
|
# セッション内のタイムゾーン変更のため、明示的にトランザクションを開始する
|
||||||
|
self.user_repository.begin()
|
||||||
|
self.user_repository.to_jst()
|
||||||
|
self.user_repository.increase_login_failed_count({'user_id': user_id})
|
||||||
|
self.user_repository.commit()
|
||||||
|
except Exception as e:
|
||||||
|
self.user_repository.rollback()
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def on_login_fail_limit_exceeded(self, user_id: str):
|
||||||
|
self.user_repository.disable_mnt_user({'user_id': user_id})
|
||||||
|
|
||||||
|
def is_login_failed_limit_exceeded(self, user_id: str):
|
||||||
|
user_record: UserMasterModel = self.user_repository.fetch_one({'user_id': user_id})
|
||||||
|
if user_record is None:
|
||||||
|
return False
|
||||||
|
return user_record.is_login_failed_limit_exceeded()
|
||||||
|
|
||||||
def __secret_hash(self, username: str):
|
def __secret_hash(self, username: str):
|
||||||
# see - https://aws.amazon.com/jp/premiumsupport/knowledge-center/cognito-unable-to-verify-secret-hash/ # noqa
|
# see - https://aws.amazon.com/jp/premiumsupport/knowledge-center/cognito-unable-to-verify-secret-hash/ # noqa
|
||||||
message = bytes(username + environment.COGNITO_CLIENT_ID, 'utf-8')
|
message = bytes(username + environment.COGNITO_CLIENT_ID, 'utf-8')
|
||||||
|
|||||||
@ -63,6 +63,7 @@ LOGOUT_REASON_BACKUP_PROCESSING = 'dump_processing'
|
|||||||
LOGOUT_REASON_NOT_LOGIN = 'not_login'
|
LOGOUT_REASON_NOT_LOGIN = 'not_login'
|
||||||
LOGOUT_REASON_DB_ERROR = 'db_error'
|
LOGOUT_REASON_DB_ERROR = 'db_error'
|
||||||
LOGOUT_REASON_UNEXPECTED = 'unexpected'
|
LOGOUT_REASON_UNEXPECTED = 'unexpected'
|
||||||
|
LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED = 'login_failed_limit_exceeded'
|
||||||
|
|
||||||
LOGOUT_REASON_MESSAGE_MAP = {
|
LOGOUT_REASON_MESSAGE_MAP = {
|
||||||
LOGOUT_REASON_DO_LOGOUT: 'Logoutしました。',
|
LOGOUT_REASON_DO_LOGOUT: 'Logoutしました。',
|
||||||
@ -72,7 +73,8 @@ LOGOUT_REASON_MESSAGE_MAP = {
|
|||||||
LOGOUT_REASON_BACKUP_PROCESSING: 'バックアップ取得を開始しました。<br>日次バッチ更新が終了するまでマスターメンテは使用できません',
|
LOGOUT_REASON_BACKUP_PROCESSING: 'バックアップ取得を開始しました。<br>日次バッチ更新が終了するまでマスターメンテは使用できません',
|
||||||
LOGOUT_REASON_NOT_LOGIN: 'Loginしてからページにアクセスしてください。',
|
LOGOUT_REASON_NOT_LOGIN: 'Loginしてからページにアクセスしてください。',
|
||||||
LOGOUT_REASON_DB_ERROR: 'DB接続に失敗しました。<br>再度Loginするか、<br>管理者にお問い合わせください。',
|
LOGOUT_REASON_DB_ERROR: 'DB接続に失敗しました。<br>再度Loginするか、<br>管理者にお問い合わせください。',
|
||||||
LOGOUT_REASON_UNEXPECTED: '予期しないエラーが発生しました。<br>再度Loginするか、<br>管理者に問い合わせてください。'
|
LOGOUT_REASON_UNEXPECTED: '予期しないエラーが発生しました。<br>再度Loginするか、<br>管理者に問い合わせてください。',
|
||||||
|
LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED: 'ログイン失敗回数の上限を超えましたので<br>アカウントをロックしました。<br>管理者に連絡してください'
|
||||||
}
|
}
|
||||||
|
|
||||||
# 新規施設担当者登録CSV(マスターメンテ)
|
# 新規施設担当者登録CSV(マスターメンテ)
|
||||||
@ -209,3 +211,6 @@ DISPLAY_USER_STOP_DIV_SHORT = {
|
|||||||
'03': '特定項目停止',
|
'03': '特定項目停止',
|
||||||
'04': '全DM停止'
|
'04': '全DM停止'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ログイン失敗回数上限(保守ユーザー)
|
||||||
|
LOGIN_FAIL_LIMIT = 10
|
||||||
Loading…
x
Reference in New Issue
Block a user