Skip to content

Commit

Permalink
Merge pull request #315 from Canway-shiisa/password_audit
Browse files Browse the repository at this point in the history
审计增加口令修改记录
  • Loading branch information
IMBlues authored Mar 21, 2022
2 parents bb8e17b + 8221c26 commit d812b41
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 11 deletions.
7 changes: 7 additions & 0 deletions src/api/bkuser_core/audit/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class OperationType(AutoLowerEnum):
EXPORT = auto()
RESTORATION = auto()

FORGET_PASSWORD = auto() # 用户通过 token 重置
ADMIN_RESET_PASSWORD = auto() # 管理员重置密码
MODIFY_PASSWORD = auto() # 用户通过旧密码修改

_choices_labels = (
(CREATE, "创建"),
(UPDATE, "更新"),
Expand All @@ -53,6 +57,9 @@ class OperationType(AutoLowerEnum):
(EXPORT, "导出"),
(IMPORT, "导入"),
(RESTORATION, "恢复"),
(FORGET_PASSWORD, "用户通过token重置密码"),
(ADMIN_RESET_PASSWORD, "管理员重置密码"),
(MODIFY_PASSWORD, "用户通过旧密码修改"),
)


Expand Down
19 changes: 16 additions & 3 deletions src/api/bkuser_core/profiles/v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
)
from bkuser_core.apis.v2.viewset import AdvancedBatchOperateViewSet, AdvancedListAPIView, AdvancedModelViewSet
from bkuser_core.audit.constants import LogInFailReason, OperationType
from bkuser_core.audit.utils import audit_general_log, create_profile_log
from bkuser_core.audit.utils import audit_general_log, create_general_log, create_profile_log
from bkuser_core.categories.constants import CategoryType
from bkuser_core.categories.loader import get_plugin_by_category
from bkuser_core.categories.models import ProfileCategory
Expand Down Expand Up @@ -75,7 +75,6 @@ class ProfileViewSet(AdvancedModelViewSet, AdvancedListAPIView):
serializer_class = local_serializers.ProfileSerializer
lookup_field = "username"
filter_backends = [ProfileSearchFilter, filters.OrderingFilter]

relation_fields = ["departments", "leader", "login_set"]

def get_object(self):
Expand Down Expand Up @@ -287,13 +286,13 @@ def create(self, request, *args, **kwargs):
)
return Response(self.serializer_class(instance).data, status=status.HTTP_201_CREATED)

@audit_general_log(OperationType.UPDATE.value)
@method_decorator(clear_cache_if_succeed)
def _update(self, request, partial):
instance = self.get_object()
serializer = local_serializers.UpdateProfileSerializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
validated_data = serializer.validated_data
operate_type = OperationType.UPDATE.value

# 只允许本地目录修改
if not ProfileCategory.objects.check_writable(instance.category_id):
Expand All @@ -320,6 +319,12 @@ def _update(self, request, partial):
update_summary = {"request": request}
# 密码修改加密
if validated_data.get("password"):
operate_type = (
OperationType.FORGET_PASSWORD.value
if request.headers.get("User-From-Token")
else OperationType.ADMIN_RESET_PASSWORD.value
)

pending_password = validated_data.get("password")
config_loader = ConfigProvider(category_id=instance.category_id)
try:
Expand Down Expand Up @@ -362,6 +367,13 @@ def _update(self, request, partial):
operator=request.operator,
extra_values=update_summary,
)

create_general_log(
operator=request.operator,
operate_type=operate_type,
operator_obj=instance,
request=request,
)
return Response(self.serializer_class(instance).data)

@swagger_auto_schema(
Expand Down Expand Up @@ -389,6 +401,7 @@ def destroy(self, request, *args, **kwargs):
"""
return super().destroy(request, *args, **kwargs)

@audit_general_log(operate_type=OperationType.MODIFY_PASSWORD.value)
@swagger_auto_schema(
query_serializer=AdvancedRetrieveSerialzier(),
request_body=local_serializers.ProfileModifyPasswordSerializer,
Expand Down
2 changes: 1 addition & 1 deletion src/api/bkuser_core/user_settings/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class SettingsEnableNamespaces(AutoLowerEnum):
(GENERAL, "通用"),
(PASSWORD, "密码"),
(CONNECTION, "连接"),
(FIELDS, "连接"),
(FIELDS, "字段"),
)


Expand Down
23 changes: 20 additions & 3 deletions src/saas/bkuser_shell/apis/viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ def get_client_ip(request) -> Optional[str]:

return ip

def _prepare_headers(self, request, force_action_id: str = "", no_auth: bool = False):
def _prepare_headers(
self, request,
force_action_id: str = "",
no_auth: bool = False,
user_from_token: bool = False
):
"""构建通用 Headers"""
headers = make_default_headers(request.user.username)
ip = self.get_client_ip(request)
Expand All @@ -90,12 +95,24 @@ def _prepare_headers(self, request, force_action_id: str = "", no_auth: bool = F
settings.API_FORCE_NO_CACHE_HEADER_NAME: True,
}
)
if user_from_token:
headers.update(
{
'user_from_token': True,
}
)

return headers

def get_api_client_by_request(self, request, force_action_id: str = "", no_auth: bool = False):
def get_api_client_by_request(
self,
request,
force_action_id: str = "",
no_auth: bool = False,
user_from_token: bool = False
):
"""从 request 中获取 api client"""
return get_api_client(self._prepare_headers(request, force_action_id, no_auth))
return get_api_client(self._prepare_headers(request, force_action_id, no_auth, user_from_token))

@staticmethod
def get_paging_results(list_func: Callable, page_size: int = 50, **kwargs) -> list:
Expand Down
10 changes: 10 additions & 0 deletions src/saas/bkuser_shell/audit/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
("export", _("导出")),
("import", _("导入")),
("restoration", _("恢复")),
("forget_password", _("用户通过token重置密码")),
("admin_reset_password", _("管理员重置密码")),
("modify_password", _("用户通过旧密码修改"))

)

OPERATION_ABOUT_PASSWORD = (
"forget_password", # 用户通过 token 重置密码
"admin_reset_password", # 管理员重置密码
"modify_password" # 用户通过旧密码修改
)

OPERATION_NAME_MAP = {x[0]: x[1] for x in OPERATION_NAME_TUPLE}
Expand Down
5 changes: 3 additions & 2 deletions src/saas/bkuser_shell/audit/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers

from .constants import LOGIN_FAILED_REASON_MAP, OPERATION_NAME_MAP, OPERATION_OBJ_NAME_MAP
from .constants import LOGIN_FAILED_REASON_MAP, OPERATION_ABOUT_PASSWORD, OPERATION_NAME_MAP, OPERATION_OBJ_NAME_MAP

PLACE_HOLDER = "--"

Expand Down Expand Up @@ -48,7 +48,8 @@ def to_representation(self, instance):
extra_value = instance["extra_value"]
categories = self.context.get("categories")
instance["target_obj"] = f"{extra_value['display_name']}<{extra_value['key']}>"
instance["operation"] = (
instance["operation"] = f"{OPERATION_NAME_MAP[extra_value['operation']]}" \
if extra_value['operation'] in OPERATION_ABOUT_PASSWORD else(
f"{OPERATION_NAME_MAP[extra_value['operation']]}" f"{OPERATION_OBJ_NAME_MAP[extra_value.get('obj_type')]}"
)

Expand Down
2 changes: 1 addition & 1 deletion src/saas/bkuser_shell/password/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def reset_by_token(self, request, validated_data):
# 由于该接口无登录态,我们只能认为访问该链接的人即用户所有者
request.user.username = profile.username

profiles_api_instance = bkuser_sdk.ProfilesApi(self.get_api_client_by_request(request))
profiles_api_instance = bkuser_sdk.ProfilesApi(self.get_api_client_by_request(request, user_from_token=True))
body = {"password": password}

# 调用后台接口重置密码
Expand Down
2 changes: 1 addition & 1 deletion src/sdk/bkuser_sdk/api/profiles_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
蓝鲸用户管理后台服务 API # noqa: E501
OpenAPI spec version: v2
Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

Expand Down

0 comments on commit d812b41

Please # to comment.