From 682454d2b345e95ffa4d6fa90b26aabfc7743589 Mon Sep 17 00:00:00 2001 From: wely Date: Wed, 13 Apr 2022 22:58:41 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E5=A2=9E=E5=8A=A0re?= =?UTF-8?q?doc,=E9=80=9A=E8=BF=87api/v1/redoc=E8=AE=BF=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/views/loginpage.py | 4 ++-- arkid/redoc/__init__.py | 0 arkid/redoc/view.py | 16 +++++++++++++ arkid/settings.py | 2 +- arkid/urls.py | 4 +++- .../__init__.py | 2 +- {arkid/login => templates}/login_enter.html | 0 templates/redoc.html | 24 +++++++++++++++++++ 8 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 arkid/redoc/__init__.py create mode 100644 arkid/redoc/view.py rename {arkid/login => templates}/login_enter.html (100%) create mode 100644 templates/redoc.html diff --git a/api/v1/views/loginpage.py b/api/v1/views/loginpage.py index f93cfcdd4..01611e957 100644 --- a/api/v1/views/loginpage.py +++ b/api/v1/views/loginpage.py @@ -97,11 +97,11 @@ def login_page(request, data: LoginPageIn = Query(...)): request.tenant = tenant login_pages = [] - responses = dispatch_event(Event(tag=CREATE_LOGIN_PAGE_AUTH_FACTOR, tenant=tenant, data={'request': request})) + responses = dispatch_event(Event(tag=CREATE_LOGIN_PAGE_AUTH_FACTOR, tenant=tenant, request=request)) for _, response in responses: login_pages.append(response) - dispatch_event(Event(tag=CREATE_LOGIN_PAGE_RULES, tenant=tenant, data={'request': request, 'login_pages': login_pages})) + dispatch_event(Event(tag=CREATE_LOGIN_PAGE_RULES, tenant=tenant, request=request, data=login_pages)) data = {} for login_page, _ in login_pages: diff --git a/arkid/redoc/__init__.py b/arkid/redoc/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/arkid/redoc/view.py b/arkid/redoc/view.py new file mode 100644 index 000000000..54ebcf289 --- /dev/null +++ b/arkid/redoc/view.py @@ -0,0 +1,16 @@ +from urllib.parse import urlsplit +from django.shortcuts import render +from django.urls import reverse +from django.views import View + + +class Redoc(View): + def get(self, request, *args, **kwargs): # pylint: disable=no-self-use unused-argument + # openapi_url = reverse('api/v1/openapi.json') + # return render(request, 'redoc.html', context={"openapi_url":openapi_url}) + http = urlsplit(request.build_absolute_uri(None)).scheme + #获得当前的HTTP或HTTPS + host = request.META['HTTP_HOST'] + #获取当前域名 + openapi_url = http + '://' + host + '/api/v1/openapi.json' + return render(request, 'redoc.html', context={'openapi_url':openapi_url}) \ No newline at end of file diff --git a/arkid/settings.py b/arkid/settings.py index c228fc706..1ef26af5a 100644 --- a/arkid/settings.py +++ b/arkid/settings.py @@ -58,7 +58,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ diff --git a/arkid/urls.py b/arkid/urls.py index 5241a94ff..ed6c56c6a 100644 --- a/arkid/urls.py +++ b/arkid/urls.py @@ -19,12 +19,14 @@ from api import v1 from arkid.login import view as login_view from arkid.core import urls as core_urls +from arkid.redoc import view as redoc_view urlpatterns = [ path("admin/", admin.site.urls), path("api/v1/", core_api.urls), path("api/v1/login", login_view.LoginEnter.as_view()), - path("api/v1/login_process", login_view.LoginProcess.as_view()) + path("api/v1/login_process", login_view.LoginProcess.as_view()), + path("api/v1/redoc", redoc_view.Redoc.as_view()) ] urlpatterns += core_urls.urlpatterns diff --git a/extension_root/com_longgui_password_auth_factor/__init__.py b/extension_root/com_longgui_password_auth_factor/__init__.py index 47eb74c72..286fe400b 100644 --- a/extension_root/com_longgui_password_auth_factor/__init__.py +++ b/extension_root/com_longgui_password_auth_factor/__init__.py @@ -29,7 +29,7 @@ class PasswordAuthFactorExtension(AuthFactorExtension): def load(self): super().load() self.register_extend_field(UserPassword, "password") - self.register_config_schema(PasswordAuthFactorSchema, 'package1') + self.register_config_schema(PasswordAuthFactorSchema) self.register_config_schema(BaseAuthFactorSchema, 'package2') def authenticate(self, event, **kwargs): diff --git a/arkid/login/login_enter.html b/templates/login_enter.html similarity index 100% rename from arkid/login/login_enter.html rename to templates/login_enter.html diff --git a/templates/redoc.html b/templates/redoc.html new file mode 100644 index 000000000..0340b6c9d --- /dev/null +++ b/templates/redoc.html @@ -0,0 +1,24 @@ + + + + Redoc + + + + + + + + + + + + + \ No newline at end of file From 675081440a6ab9cc4321c7c5c75d07ab975b5fbb Mon Sep 17 00:00:00 2001 From: wely Date: Wed, 13 Apr 2022 23:36:18 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=F0=9F=90=9B=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/views/loginpage.py | 14 ++--- arkid/core/api.py | 6 +-- arkid/core/models.py | 110 +++++++++++++++++++------------------- arkid/core/translation.py | 7 +-- 4 files changed, 66 insertions(+), 71 deletions(-) diff --git a/api/v1/views/loginpage.py b/api/v1/views/loginpage.py index 01611e957..0950adf62 100644 --- a/api/v1/views/loginpage.py +++ b/api/v1/views/loginpage.py @@ -85,8 +85,8 @@ class LoginPageOut(Schema): tenant: LoginPageTenantSchema -register_event(CREATE_LOGIN_PAGE_AUTH_FACTOR, '认证因素生成登录页面') -register_event(CREATE_LOGIN_PAGE_RULES, '登录页面生成规则') +register_event(CREATE_LOGIN_PAGE_AUTH_FACTOR, _('create login page by auth factor','认证因素生成登录页面')) +register_event(CREATE_LOGIN_PAGE_RULES, _('create login page rules','登录页面生成规则')) @api.get("/login_page/", response=LoginPageOut, auth=None) @@ -125,19 +125,19 @@ def login_page(request, data: LoginPageIn = Query(...)): data[k]['name'] = k if data.get(AuthFactorExtension.RESET_PASSWORD): - bottom = {"label": "忘记密码", "gopage": AuthFactorExtension.RESET_PASSWORD} + bottom = {"label": _("Forget Password", "忘记密码"), "gopage": AuthFactorExtension.RESET_PASSWORD} data[AuthFactorExtension.LOGIN]['bottoms'].insert(0, bottom) - bottom = {"prepend": "已有账号,", "label": "立即登录", "gopage": AuthFactorExtension.LOGIN} + bottom = {"prepend": _("Existing Account,", "已有账号,"), "label": _("Login Now","立即登录"), "gopage": AuthFactorExtension.LOGIN} data[AuthFactorExtension.RESET_PASSWORD]['bottoms'].insert(0, bottom) if data.get(AuthFactorExtension.REGISTER): - bottom = {"prepend": "还没有账号,", "label": "立即注册", "gopage": AuthFactorExtension.REGISTER} + bottom = {"prepend": _("No Account,","还没有账号,"), "label": _("Register Now","立即注册"), "gopage": AuthFactorExtension.REGISTER} data[AuthFactorExtension.LOGIN]['bottoms'].insert(0, bottom) - bottom = {"prepend": "已有账号,", "label": "立即登录", "gopage": AuthFactorExtension.LOGIN} + bottom = {"prepend": _("Existing Account,", "已有账号,"), "label": _("Login Now","立即登录"), "gopage": AuthFactorExtension.LOGIN} data[AuthFactorExtension.REGISTER]['bottoms'].insert(0, bottom) if data.get(AuthFactorExtension.REGISTER) and data.get(AuthFactorExtension.RESET_PASSWORD): - bottom = {"prepend": "还没有账号,", "label": "立即注册", "gopage": AuthFactorExtension.REGISTER} + bottom = {"prepend": _("No Account,","还没有账号,"), "label": _("Register Now","立即注册"), "gopage": AuthFactorExtension.REGISTER} data[AuthFactorExtension.RESET_PASSWORD]['bottoms'].insert(0, bottom) return { diff --git a/arkid/core/api.py b/arkid/core/api.py index 79e21952b..e7ecb705e 100644 --- a/arkid/core/api.py +++ b/arkid/core/api.py @@ -73,13 +73,13 @@ def authenticate(self, request, token): token = ExpiringToken.objects.get(token=token) if not token.user.is_active: - raise Exception(_('User inactive or deleted')) + raise Exception(_('User inactive or deleted','用户无效或被删除')) if token.expired(): - raise Exception(_('Token has expired')) + raise Exception(_('Token has expired','秘钥已经过期')) except ExpiringToken.DoesNotExist: - logger.error(_("Invalid token")) + logger.error(_("Invalid token","无效的秘钥")) return except Exception as err: logger.error(err) diff --git a/arkid/core/models.py b/arkid/core/models.py index a67716583..9a2cd3725 100644 --- a/arkid/core/models.py +++ b/arkid/core/models.py @@ -30,8 +30,8 @@ class Meta(object): verbose_name_plural = _("user", "用户") username = models.CharField(max_length=128, blank=False) - avatar = models.URLField(verbose_name=_('头像'), blank=True) - is_platform_user = models.BooleanField(default=False, verbose_name=_('是否是平台用户')) + avatar = models.URLField(verbose_name=_('Avatar','头像'), blank=True) + is_platform_user = models.BooleanField(default=False, verbose_name=_('is platform user','是否是平台用户')) tenants = models.ManyToManyField( 'Tenant', @@ -44,8 +44,8 @@ class Meta(object): class UserGroup(ExpandModel, BaseModel): class Meta(object): - verbose_name = _("用户分组") - verbose_name_plural = _("用户分组") + verbose_name = _("User Group","用户分组") + verbose_name_plural = _("User Group","用户分组") tenant = models.ForeignKey( 'Tenant', blank=False, on_delete=models.PROTECT @@ -63,7 +63,7 @@ class Meta(object): blank=True, related_name="user_set", related_query_name="user", - verbose_name=_('用户列表') + verbose_name=_('User List','用户列表') ) def __str__(self) -> str: @@ -77,20 +77,20 @@ def children(self): class App(ExpandModel, BaseModel): class Meta(object): - verbose_name = _("应用") - verbose_name_plural = _("应用") + verbose_name = _("APP","应用") + verbose_name_plural = _("APP", "应用") tenant = models.ForeignKey( 'Tenant', blank=False, on_delete=models.PROTECT ) - name = models.CharField(max_length=128, verbose_name=_('应用名称')) - url = models.CharField(max_length=1024, blank=True, verbose_name=_('应用地址')) - logo = models.CharField(max_length=1024, blank=True, null=True, default='', verbose_name=_('应用图标')) - description = models.TextField(blank=True, null=True, verbose_name=_('应用描述')) - type = models.CharField(max_length=128, verbose_name=_('应用类型')) - data = models.JSONField(blank=True, default=dict, verbose_name=_('应用配置')) + name = models.CharField(max_length=128, verbose_name=_('name','名称')) + url = models.CharField(max_length=1024, blank=True, verbose_name=_('url','地址')) + logo = models.CharField(max_length=1024, blank=True, null=True, default='', verbose_name=_('logo','图标')) + description = models.TextField(blank=True, null=True, verbose_name=_('description','描述')) + type = models.CharField(max_length=128, verbose_name=_('type','类型')) + data = models.JSONField(blank=True, default=dict, verbose_name=_('data','配置')) secret = models.CharField( - max_length=255, blank=True, null=True, default='', verbose_name=_('应用密钥') + max_length=255, blank=True, null=True, default='', verbose_name=_('secret','密钥') ) def __str__(self) -> str: @@ -100,8 +100,8 @@ def __str__(self) -> str: class AppGroup(ExpandModel, BaseModel): class Meta(object): - verbose_name = _("应用分组") - verbose_name_plural = _("应用分组") + verbose_name = _("APP Group","应用分组") + verbose_name_plural = _("APP Group","应用分组") tenant = models.ForeignKey( 'Tenant', blank=False, on_delete=models.PROTECT @@ -119,7 +119,7 @@ class Meta(object): blank=True, related_name="app_set", related_query_name="app", - verbose_name=_('应用列表') + verbose_name=_('APP List', '应用列表') ) def __str__(self) -> str: @@ -133,23 +133,21 @@ def children(self): class PermissionAbstract(ExpandModel, BaseModel): class Meta(object): - verbose_name = _("权限") - verbose_name_plural = _("权限") abstract = True CATEGORY_CHOICES = ( - ('entry', '入口'), - ('api', 'API'), - ('data', '数据'), - ('group', '分组'), - ('ui', '界面'), - ('other', '其它'), + ('entry', _('entry','入口')), + ('api', _('API','接口')), + ('data', _('data','数据')), + ('group', _('group','分组')), + ('ui', _('UI','界面')), + ('other', _('other','其它')), ) - name = models.CharField(verbose_name=_('名称'), max_length=255) - code = models.CharField(verbose_name=_('编码'), max_length=100) + name = models.CharField(verbose_name=_('Name','名称'), max_length=255) + code = models.CharField(verbose_name=_('Code','编码'), max_length=100) tenant = models.ForeignKey( - 'Tenant', default=None, on_delete=models.PROTECT, verbose_name=_('租户') + 'Tenant', default=None, on_delete=models.PROTECT, verbose_name=_('Tenant','租户') ) app = models.ForeignKey( App, @@ -157,17 +155,17 @@ class Meta(object): default=None, null=True, blank=True, - verbose_name=_('应用') + verbose_name=_('APP','应用') ) category = models.CharField( choices=CATEGORY_CHOICES, default="other", max_length=100, - verbose_name=_("类型"), + verbose_name=_('category',"类型"), ) is_system = models.BooleanField( default=True, - verbose_name=_('是否是系统权限') + verbose_name=_('System Permission','是否是系统权限') ) def __str__(self): @@ -177,8 +175,8 @@ def __str__(self): class Permission(PermissionAbstract): class Meta(object): - verbose_name = _("权限分组") - verbose_name_plural = _("权限分组") + verbose_name = _("Permission", "权限") + verbose_name_plural = _("Permission", "权限") parent = models.ForeignKey( 'Permission', @@ -186,14 +184,14 @@ class Meta(object): blank=True, on_delete=models.PROTECT, related_name='children', - verbose_name=_('父权限分组') + verbose_name=_('Parent', '父权限分组') ) permissions = models.ManyToManyField( 'Permission', blank=True, related_name="permission_set", related_query_name="permission", - verbose_name=_('权限列表') + verbose_name=_('Permission List','权限列表') ) def __str__(self) -> str: @@ -207,20 +205,20 @@ def children(self): class Approve(ExpandModel, BaseModel): class Meta(object): - verbose_name = _("审批动作") - verbose_name_plural = _("审批动作") + verbose_name = _('Approve',"审批动作") + verbose_name_plural = _('Approve',"审批动作") STATUS_CHOICES = ( - ('wait', '待审批'), - ('pass', '通过'), - ('deny', '拒绝'), + ('wait', _('Wait','待审批')), + ('pass', _('Pass','通过')), + ('deny', _('Deny','拒绝')), ) - name = models.CharField(verbose_name=_('名称'), max_length=255) - code = models.CharField(verbose_name=_('编码'), max_length=100) - description = models.TextField(blank=True, null=True, verbose_name=_('备注')) + name = models.CharField(verbose_name=_('Name','名称'), max_length=255) + code = models.CharField(verbose_name=_('Code','编码'), max_length=100) + description = models.TextField(blank=True, null=True, verbose_name=_('Description','备注')) tenant = models.ForeignKey( - 'Tenant', default=None, on_delete=models.PROTECT, verbose_name=_('租户') + 'Tenant', default=None, on_delete=models.PROTECT, verbose_name=_('Tenant','租户') ) app = models.ForeignKey( App, @@ -228,17 +226,17 @@ class Meta(object): default=None, null=True, blank=True, - verbose_name=_('应用') + verbose_name=_('APP','应用') ) status = models.CharField( choices=STATUS_CHOICES, default="wait", max_length=100, - verbose_name=_("状态"), + verbose_name=_('Status',"状态"), ) data = models.JSONField( default=dict, - verbose_name=_("数据"), + verbose_name=_('Data',"数据"), ) def __str__(self): @@ -248,15 +246,15 @@ def __str__(self): class ExpiringToken(models.Model): class Meta(object): - verbose_name = _("Token") - verbose_name_plural = _("Token") + verbose_name = _("Token","秘钥") + verbose_name_plural = _("Token","秘钥") user = models.OneToOneField( 'User', related_name='auth_token', - on_delete=models.CASCADE, verbose_name=_("User") + on_delete=models.CASCADE, verbose_name=_("User",'用户') ) - token = models.CharField(_("Token"), max_length=40, primary_key=True) - created = models.DateTimeField(_("Created"), auto_now_add=True) + token = models.CharField(_("Token",'秘钥'), max_length=40, primary_key=True) + created = models.DateTimeField(_("Created",'创建时间'), auto_now_add=True) def expired(self, tenant): """Return boolean indicating token expiration.""" @@ -291,8 +289,8 @@ def __str__(self): class TenantConfig(ExpandModel, BaseModel): class Meta(object): - verbose_name = _("租户配置") - verbose_name_plural = _("租户配置") + verbose_name = _('Tenant Config',"租户配置") + verbose_name_plural = _('Tenant Config',"租户配置") - tenant = models.ForeignKey('Tenant', blank=False, on_delete=models.PROTECT, verbose_name=_('租户')) - token_duration_minutes = models.IntegerField(blank=False, default=24*60, verbose_name=_('token有效时长(分钟)')) + tenant = models.ForeignKey('Tenant', blank=False, on_delete=models.PROTECT, verbose_name=_('Tenant','租户')) + token_duration_minutes = models.IntegerField(blank=False, default=24*60, verbose_name=_('Token Duration Minutes','Token有效时长(分钟)')) diff --git a/arkid/core/translation.py b/arkid/core/translation.py index 89ee1716e..79e1be28f 100644 --- a/arkid/core/translation.py +++ b/arkid/core/translation.py @@ -6,12 +6,9 @@ default_lang_maps = {} -def gettext_default(id,msg="",lang="en"): +def gettext_default(id,msg=None,lang="zh-hans"): if not msg: - if lang=='en': - msg = id - else: - raise Exception("invalid params") + msg = id if lang in default_lang_maps.keys(): default_lang_maps[lang][id] = msg