Skip to content

Commit

Permalink
feat: bkpaas-auth 3.0.0 (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
narasux authored Oct 16, 2024
1 parent 17a16b8 commit 0ff708a
Show file tree
Hide file tree
Showing 17 changed files with 551 additions and 642 deletions.
138 changes: 71 additions & 67 deletions .github/workflows/bkpaas-auth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ name: CI Check for bkpaas-auth

on:
push:
branches: [ master ]
branches: [master]
paths:
- 'sdks/bkpaas-auth/**'
- "sdks/bkpaas-auth/**"
pull_request:
branches: [ master ]
branches: [master]
paths:
- 'sdks/bkpaas-auth/**'
- "sdks/bkpaas-auth/**"
workflow_dispatch:
release:
types: [published]
Expand All @@ -18,79 +18,83 @@ jobs:
runs-on: macos-latest
continue-on-error: true
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Format with isort
run: |
pip install isort==5.9.2
isort sdks/ --settings-path=sdks/bkpaas-auth/pyproject.toml
- name: Format with black
run: |
pip install black==21.7b0 click==8.0.4
black sdks/ --config=sdks/bkpaas-auth/pyproject.toml
- name: Lint with flake8
run: |
pip install flake8==4.0.1 pyproject-flake8==0.0.1a4
pflake8 sdks/ --config=sdks/bkpaas-auth/pyproject.toml
- name: Lint with mypy
run: |
pip install mypy==0.910 types-requests==2.25.0 types-setuptools==57.0.0 types-dataclasses==0.1.5 types-six==0.1.7 types-toml==0.1.3
mypy sdks/bkpaas-auth --config-file=sdks/bkpaas-auth/pyproject.toml
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.11
- name: Format with isort
working-directory: sdks/bkpaas-auth
run: |
pip install isort==5.12.0
isort . --settings-path=pyproject.toml
- name: Format with black
working-directory: sdks/bkpaas-auth
run: |
pip install black==23.7.0 click==8.1.6
black . --config=pyproject.toml
- name: Lint with flake8
working-directory: sdks/bkpaas-auth
run: |
pip install flake8==4.0.1 pyproject-flake8==0.0.1a5
pflake8 . --config=pyproject.toml
- name: Lint with mypy
working-directory: sdks/bkpaas-auth
run: |
pip install mypy==1.12.0 types-mock==4.0.15.2 types-requests==2.32.0.20241016 types-six==1.16.21.20241009
mypy . --config-file=pyproject.toml
test:
strategy:
fail-fast: false
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ["3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Set up Poetry
uses: abatilo/actions-poetry@v2.1.0
with:
poetry-version: 1.1.13
- name: Install dependencies
working-directory: sdks/bkpaas-auth
run: |
poetry export --without-hashes --dev -o requirements-dev.txt
python -m pip install --upgrade pip
python -m pip install -r requirements-dev.txt
python -m pip install tox-gh-actions==2.8.1
- name: Run test with tox targets for ${{ matrix.python-version }}
working-directory: sdks/bkpaas-auth
run: tox
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Set up Poetry
uses: abatilo/actions-poetry@v2.3.0
with:
poetry-version: 1.5.1
- name: Install dependencies
working-directory: sdks/bkpaas-auth
run: |
poetry export --without-hashes --dev -o requirements-dev.txt
python -m pip install --upgrade pip
python -m pip install -r requirements-dev.txt
python -m pip install tox-gh-actions==2.8.1
- name: Run test with tox targets for ${{ matrix.python-version }}
working-directory: sdks/bkpaas-auth
run: tox

build:
runs-on: macos-latest
if: github.event.release && contains(github.event.release.tag_name, 'bkpaas-auth')
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Set up Poetry
uses: abatilo/actions-poetry@v2.1.0
with:
poetry-version: 1.1.13
- name: Build bkpaas-auth
run: |
cd sdks/bkpaas-auth
poetry install
poetry build
echo "${{ github.event.relesae.tag_name }} ${{ github.sha }}" > Release.txt
cat Release.txt
- name: Release
uses: softprops/action-gh-release@v1
with:
files: |
Release.txt
sdks/bkpaas-auth/dist/*
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Set up Poetry
uses: abatilo/actions-poetry@v2.3.0
with:
poetry-version: 1.5.1
- name: Build bkpaas-auth
run: |
cd sdks/bkpaas-auth
poetry install
poetry build
echo "${{ github.event.relesae.tag_name }} ${{ github.sha }}" > Release.txt
cat Release.txt
- name: Release
uses: softprops/action-gh-release@v1
with:
files: |
Release.txt
sdks/bkpaas-auth/dist/*
2 changes: 1 addition & 1 deletion .github/workflows/blue-krill.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
run: tox
build:
runs-on: macos-latest
if: github.event.release && contains(github.event.release.tag_name, 'blue_krill')
if: github.event.release && contains(github.event.release.tag_name, 'blue-krill')
steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand Down
6 changes: 5 additions & 1 deletion sdks/bkpaas-auth/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# 版本历史

## 3.0.0
- BreakChange: 不再支持 Python 3.6,3.7
- BreakChange: Django 版本要求 >=4.2,<5.0

## 2.1.0
- fix: 修复 APIGatewayAuthBackend 不兼容 ^3.0.0 以上的 apigw_manager
- fix: 修复 APIGatewayAuthBackend 不兼容 ^3.0.0 以上的 apigw_manager

## 2.0.8
- 将认证信息标准化到请求头 X-Bkapi-Authorization 中
Expand Down
2 changes: 1 addition & 1 deletion sdks/bkpaas-auth/bkpaas_auth/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
__version__ = "2.1.0"
__version__ = "3.0.0"


def get_user_by_user_id(user_id: str, username_only: bool = True):
Expand Down
6 changes: 4 additions & 2 deletions sdks/bkpaas-auth/bkpaas_auth/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class UniversalAuthBackend:
"""

request: HttpRequest
plugin: Union[BkTicketPlugin, BkTokenPlugin]
request_backend: Union[RequestBackend, TokenRequestBackend]

def __init__(self):
self.backend_type = bkauth_settings.BACKEND_TYPE
Expand Down Expand Up @@ -215,11 +217,11 @@ def authenticate_with_signature_v1(self, request, api_name, bk_username, verifie
if get_user_parameters == v3_parameters:
authenticate = authenticate_with_signature_v3
else:
authenticate = authenticate_with_signature_v1
authenticate = authenticate_with_signature_v1 # type: ignore
del get_user_parameters
del v3_parameters
except ImportError:
authenticate = authenticate_with_signature_v1
authenticate = authenticate_with_signature_v1 # type: ignore

def get_user(self, user_id):
raise NotImplementedError(
Expand Down
2 changes: 1 addition & 1 deletion sdks/bkpaas-auth/bkpaas_auth/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Settings:

def reload(self):
for f in fields(self):
setattr(self, f.name, f.default_factory())
setattr(self, f.name, f.default_factory()) # type: ignore


bkauth_settings = Settings()
Expand Down
41 changes: 41 additions & 0 deletions sdks/bkpaas-auth/bkpaas_auth/core/algorithms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-

class ARC4:
"""ARC4 算法的实现
注意:ARC4 加密算法很容易被破解,目前项目中仅用于解编码(类似 base64 的作用)
"""

def __init__(self, key):
assert (isinstance(key, (bytes, bytearray)))

s = list(range(0x100))
j = 0
for i in range(0x100):
j = (s[i] + key[i % len(key)] + j) & 0xff
s[i], s[j] = s[j], s[i]

self.s = s
self.key_stream = self._key_stream_generator()

def encrypt(self, data):
"""加密数据"""
return self._crypt(data)

def decrypt(self, data):
"""解密数据"""
return self._crypt(data)

def _crypt(self, data):
assert (isinstance(data, (bytes, bytearray)))
return bytes([a ^ b for a, b in zip(data, self.key_stream)])

def _key_stream_generator(self):
s = self.s.copy()
x = y = 0
while True:
x = (x + 1) & 0xff
y = (s[x] + y) & 0xff
s[x], s[y] = s[y], s[x]
i = (s[x] + s[y]) & 0xff
yield s[i]
27 changes: 3 additions & 24 deletions sdks/bkpaas-auth/bkpaas_auth/core/encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,10 @@
import binascii
from typing import Tuple, Union

from cryptography.hazmat.backends.openssl.backend import GetCipherByName, backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
from six import ensure_binary, ensure_text

from bkpaas_auth.core.constants import ProviderType


class _ARC4(algorithms.ARC4):
"""ARC4 should support key sizes bellow 40-2048 bits,
but algorithms.ARC4 only support the kes size to be in [40, 56, 64, 80, 128, 160, 192, 256] bytes.
In order to support the key='jdvoqu3o4', we must overwrite the field `key_sizes` to remove the restriction.
This is the reason why we must implement another ARC4 algorithm.
"""

key_sizes = frozenset(range(40, 2049, 4))


backend.register_cipher_adapter(_ARC4, type(None), GetCipherByName("rc4"))
from bkpaas_auth.core.algorithms import ARC4


class BluekingUserIdEncoder:
Expand All @@ -38,10 +23,7 @@ def encode(self, provider_type: Union[int, ProviderType], username: Union[str, b
"""
id_prefix = ProviderType(provider_type).get_id_prefix()

algorithm = _ARC4(ensure_binary(self.secret_key))
cipher = Cipher(algorithm, mode=None)
encryptor = cipher.encryptor()
encoded = encryptor.update(ensure_binary(username))
encoded = ARC4(ensure_binary(self.secret_key)).encrypt(ensure_binary(username))
return id_prefix + ensure_text(binascii.hexlify(encoded))

def decode(self, user_id: Union[str, bytes]) -> Tuple[int, str]:
Expand All @@ -53,10 +35,7 @@ def decode(self, user_id: Union[str, bytes]) -> Tuple[int, str]:
_provider_type, username = user_id[:2], user_id[2:]
provider_type = int(_provider_type)

algorithm = _ARC4(ensure_binary(self.secret_key))
cipher = Cipher(algorithm, mode=None)
decryptor = cipher.decryptor()
decoded = decryptor.update(binascii.unhexlify(username))
decoded = ARC4(ensure_binary(self.secret_key)).decrypt(binascii.unhexlify(username))
return provider_type, ensure_text(decoded)


Expand Down
2 changes: 2 additions & 0 deletions sdks/bkpaas-auth/bkpaas_auth/core/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def _get_and_cache_user_info(cache_key, user_params, response_ok_checker):
)
if not is_success:
raise ServiceError('Unable to get user info')
if not isinstance(result, dict):
raise ValueError(f'response type expect dict, got: {result}')

if not response_ok_checker(result):
logger.error(
Expand Down
4 changes: 4 additions & 0 deletions sdks/bkpaas-auth/bkpaas_auth/core/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def request_username(self, **credentials):
)
if not is_success:
raise ServiceError('unable to fetch token services')
if not isinstance(resp, dict):
raise ValueError(f'response type expect dict, got: {resp}')

# API 返回格式为:{"result": true, "code": 0, "message": "", "data": {"bk_username": "xxx"}}
code = resp.get('code')
Expand Down Expand Up @@ -69,6 +71,8 @@ def request_username(self, **credentials):
is_success, resp = http_get(bkauth_settings.USER_COOKIE_VERIFY_URL, params=credentials, timeout=10)
if not is_success:
raise ServiceError('unable to fetch token services')
if not isinstance(resp, dict):
raise ValueError(f'response type expect dict, got: {resp}')

# API 返回格式为:{"msg": "", "data": {"username": "xxx"}, "ret": 0}
if resp.get('ret') != 0:
Expand Down
4 changes: 2 additions & 2 deletions sdks/bkpaas-auth/bkpaas_auth/middlewares.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.contrib import auth
from django.http import HttpRequest, HttpResponse
from django.utils.deprecation import MiddlewareMixin
from django.utils.encoding import force_text
from django.utils.encoding import force_str

from bkpaas_auth.backends import UniversalAuthBackend
from bkpaas_auth.core.constants import ACCESS_PERMISSION_DENIED_CODE
Expand Down Expand Up @@ -87,7 +87,7 @@ def authenticate_and_login(self, request: HttpRequest, credentials: Dict[str, st
request.session['bkpaas_authenticated_at'] = time.time()
request.session['auth_credentials'] = credentials
# python3 compatibility
request.session['user_token'] = force_text(pickle.dumps(user.token), 'latin1')
request.session['user_token'] = force_str(pickle.dumps(user.token), 'latin1')

# Calling `auth.login` will rotate CSRF token and modify user session, only do this when the authenticated
# user was different with the user stored in session. Otherwise CSRF token validation may fail due to the
Expand Down
2 changes: 1 addition & 1 deletion sdks/bkpaas-auth/bkpaas_auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def __init__(self, token=None, provider_type=None, username=None, **info_fields)

self.update_user_info(info_fields, overwrite_all=True)
# Use chinesename as nickname
if not self.nickname and self.chinese_name:
if not self.nickname and self.chinese_name: # type: ignore
self.nickname = self.chinese_name
self.token = token

Expand Down
Loading

0 comments on commit 0ff708a

Please sign in to comment.