-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): retrieve tenant user by id (#2022)
- Loading branch information
Showing
10 changed files
with
302 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. | ||
from collections import namedtuple | ||
|
||
from django.conf import settings | ||
from django.contrib.auth.models import AnonymousUser | ||
from rest_framework import exceptions | ||
from rest_framework.authentication import BaseAuthentication, get_authorization_header | ||
|
||
InnerBearerToken = namedtuple("InnerBearerToken", ["verified"]) | ||
|
||
|
||
class InnerBearerTokenAuthentication(BaseAuthentication): | ||
keyword = "Bearer" | ||
|
||
def __init__(self): | ||
self.allowed_tokens = [settings.BK_APIGW_TO_BK_USER_INNER_BEARER_TOKEN] | ||
|
||
def authenticate(self, request): | ||
auth = get_authorization_header(request).split() | ||
if not auth or auth[0].lower() != self.keyword.lower().encode(): | ||
return None | ||
|
||
if len(auth) == 1: | ||
raise exceptions.AuthenticationFailed("Invalid token header. No credentials provided.") | ||
if len(auth) > 2: # noqa: PLR2004 | ||
raise exceptions.AuthenticationFailed("Invalid token header. Token string should not contain spaces.") | ||
|
||
try: | ||
token = auth[1].decode() | ||
except UnicodeError: | ||
raise exceptions.AuthenticationFailed( | ||
"Invalid token header. Token string should not contain invalid characters." | ||
) | ||
|
||
# Verify Bearer Token | ||
if token not in self.allowed_tokens: | ||
raise exceptions.AuthenticationFailed("Invalid token.") | ||
|
||
# Mark Verified Bearer Token | ||
request.inner_bearer_token = InnerBearerToken(verified=True) | ||
|
||
return AnonymousUser(), None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. | ||
from rest_framework.permissions import BasePermission | ||
|
||
|
||
class IsInnerBearerTokenAuthenticated(BasePermission): | ||
def has_permission(self, request, view): | ||
return hasattr(request, "inner_bearer_token") and request.inner_bearer_token.verified |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
urlpatterns = [ | ||
path( | ||
"tenant-users/<str:tenant_user_id>/", views.TenantUserRetrieveApi.as_view(), name="apigw.tenant_user.retrieve" | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. | ||
from rest_framework import generics | ||
from rest_framework.response import Response | ||
|
||
from bkuser.apps.tenant.models import TenantUser | ||
from bkuser.common.error_codes import error_codes | ||
|
||
from .authentications import InnerBearerTokenAuthentication | ||
from .permissions import IsInnerBearerTokenAuthenticated | ||
|
||
|
||
class TenantUserRetrieveApi(generics.RetrieveAPIView): | ||
""" | ||
查询用户信息 | ||
Note: 网关内部接口对性能要求较高,所以不进行序列化,且查询必须按字段 | ||
TODO:后续根据耗时统计进行 Cache 优化 | ||
""" | ||
|
||
authentication_classes = [InnerBearerTokenAuthentication] | ||
permission_classes = [IsInnerBearerTokenAuthenticated] | ||
|
||
def get(self, request, *args, **kwargs): | ||
tenant_user_id = kwargs["tenant_user_id"] | ||
|
||
# [only] 用于减少查询字段,仅查询必要字段 | ||
tenant_user = TenantUser.objects.filter(id=tenant_user_id).only("tenant_id").first() | ||
if not tenant_user: | ||
raise error_codes.OBJECT_NOT_FOUND.f(f"user({tenant_user_id}) not found", replace=True) | ||
|
||
return Response({"tenant_id": tenant_user.tenant_id}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# -*- coding: utf-8 -*- | ||
# TencentBlueKing is pleased to support the open source community by making | ||
# 蓝鲸智云 - 用户管理 (bk-user) available. | ||
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. | ||
# Licensed under the MIT License (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://opensource.org/licenses/MIT | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under | ||
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, | ||
# either express or implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# We undertake not to change the open source license (MIT license) applicable | ||
# to the current version of the project delivered to anyone in the future. | ||
from unittest import mock | ||
|
||
import pytest | ||
from bkuser.apis.apigw.authentications import InnerBearerToken | ||
from bkuser.apps.data_source.constants import DataSourceTypeEnum | ||
from bkuser.apps.data_source.models import DataSource | ||
from bkuser.apps.tenant.constants import TenantUserIdRuleEnum | ||
from bkuser.apps.tenant.models import TenantUserIDGenerateConfig | ||
from bkuser.plugins.local.models import LocalDataSourcePluginConfig | ||
from django.contrib.auth.models import AnonymousUser | ||
from rest_framework.test import APIClient | ||
|
||
from tests.test_utils.data_source import init_data_source_users_depts_and_relations | ||
from tests.test_utils.tenant import sync_users_depts_to_tenant | ||
|
||
|
||
def mock_token_authenticate(self, request): | ||
request.inner_bearer_token = InnerBearerToken(verified=True) | ||
return AnonymousUser(), None | ||
|
||
|
||
@pytest.fixture | ||
def apigw_api_client() -> APIClient: | ||
client = APIClient() | ||
|
||
with mock.patch( | ||
"bkuser.apis.apigw.authentications.InnerBearerTokenAuthentication.authenticate", new=mock_token_authenticate | ||
): | ||
yield client | ||
|
||
|
||
@pytest.fixture | ||
def default_tenant_user_data(default_tenant, local_ds_plugin_cfg, local_ds_plugin) -> DataSource: | ||
"""默认租户的本地数据源数据""" | ||
data_source = DataSource.objects.create( | ||
owner_tenant_id=default_tenant.id, | ||
type=DataSourceTypeEnum.REAL, | ||
plugin=local_ds_plugin, | ||
plugin_config=LocalDataSourcePluginConfig(**local_ds_plugin_cfg), | ||
) | ||
init_data_source_users_depts_and_relations(data_source) | ||
|
||
# 设置租户用户生成规则表,让 tenant_user_id 与 数据源 username 一样 | ||
TenantUserIDGenerateConfig.objects.create( | ||
data_source=data_source, | ||
target_tenant_id=default_tenant.id, | ||
rule=TenantUserIdRuleEnum.USERNAME, | ||
) | ||
|
||
sync_users_depts_to_tenant(default_tenant, data_source) | ||
return data_source |
Oops, something went wrong.