add admin login and optimize the swagger definition

pull/21891/head
ytqh 1 year ago
parent bc039efdaf
commit db36e3edf9

@ -0,0 +1,8 @@
from flask import Blueprint
from libs.external_api import ExternalApi
bp = Blueprint("admin_api", __name__, url_prefix="/admin")
api = ExternalApi(bp)
from .auth import login

@ -0,0 +1,124 @@
from flask import Blueprint
from flask_restful import Api, Resource # type: ignore
from controllers.admin import api
class SendVerificationCodeApi(Resource):
def post(self):
"""Send verification code to admin's phone number.
---
tags:
- admin
summary: Send Verification Code
description: Sends a verification code to the provided admin phone number for authentication
parameters:
- in: body
name: body
required: true
schema:
type: object
required:
- phone
properties:
phone:
type: string
description: Admin's phone number
example: "13800138000"
responses:
200:
description: Code sent successfully
schema:
type: object
properties:
success:
type: boolean
message:
type: string
400:
description: Invalid phone number format
404:
description: Phone number not registered as admin
"""
pass
class LoginApi(Resource):
def post(self):
"""Admin login with phone number and verification code.
---
tags:
- admin
summary: Admin Login
description: Authenticates an admin using phone number and verification code
parameters:
- in: body
name: body
required: true
schema:
type: object
required:
- phone
- code
properties:
phone:
type: string
description: Admin's phone number
example: "13800138000"
code:
type: string
description: Verification code
example: "123456"
responses:
200:
description: Login successful
schema:
type: object
properties:
token:
type: string
description: JWT access token
user:
type: object
properties:
id:
type: string
phone:
type: string
name:
type: string
role:
type: string
enum: [admin, super_admin]
400:
description: Invalid or expired verification code
404:
description: Phone number not registered
"""
pass
class LogoutApi(Resource):
def post(self):
"""Admin logout.
---
tags:
- admin
summary: Admin Logout
description: Logs out the authenticated admin and invalidates the JWT token
security:
- JWT: []
responses:
200:
description: Logout successful
schema:
type: object
properties:
success:
type: boolean
401:
description: Missing or invalid token
"""
pass
# Register the resources
api.add_resource(SendVerificationCodeApi, '/auth/send-code')
api.add_resource(LoginApi, '/auth/login')
api.add_resource(LogoutApi, '/auth/logout')

@ -4,8 +4,6 @@ import flask_login # type: ignore
from flask import request
from flask_restful import Resource, reqparse # type: ignore
import services
from configs import dify_config
from constants.languages import languages
from controllers.service_api import api
from controllers.service_api.auth.error import (
@ -21,10 +19,8 @@ from controllers.service_api.error import (
)
from events.tenant_event import tenant_was_created
from libs.helper import email, extract_remote_ip
from libs.password import valid_password
from models.account import Account
from services.account_service import AccountService, RegisterService, TenantService
from services.billing_service import BillingService
from services.account_service import AccountService, TenantService
from services.errors.account import AccountRegisterError
from services.errors.workspace import WorkSpaceNotAllowedCreateError
from services.feature_service import FeatureService
@ -34,11 +30,23 @@ class LogoutApi(Resource):
def get(self):
"""Logout user.
---
tags:
- user-end
summary: Logout User
description: Logs out the authenticated user and invalidates the session.
description: Logs out the authenticated user and invalidates the session
security:
- JWT: []
responses:
200:
description: Successfully logged out.
description: Successfully logged out
schema:
type: object
properties:
result:
type: string
example: "success"
401:
description: Unauthorized, invalid or missing token
"""
account = cast(Account, flask_login.current_user)
if isinstance(account, flask_login.AnonymousUserMixin):
@ -52,26 +60,42 @@ class EmailCodeLoginSendEmailApi(Resource):
def post(self):
"""Send email code for login.
---
tags:
- user-end
summary: Email Code Login Email Sending
description: Sends an email with a verification code for login.
description: Sends an email with a verification code for login
parameters:
- in: body
name: email
name: body
required: true
type: string
description: The user's email.
- in: body
name: language
required: false
type: string
description: Preferred language for the email.
schema:
type: object
required:
- email
properties:
email:
type: string
description: The user's email
language:
type: string
description: Preferred language for the email
enum: ["en-US", "zh-Hans"]
responses:
200:
description: Successfully sent the email code along with token data.
description: Successfully sent the email code
schema:
type: object
properties:
result:
type: string
example: "success"
data:
type: object
description: Token data
429:
description: Too many requests, IP limit reached.
description: Too many requests, IP limit reached
404:
description: Account not found.
description: Account not found
"""
parser = reqparse.RequestParser()
parser.add_argument("email", type=email, required=True, location="json")
@ -106,29 +130,44 @@ class EmailCodeLoginApi(Resource):
def post(self):
"""Login using email code.
---
tags:
- user-end
summary: Email Code Login
description: Allows the user to login using a verification code and token sent via email.
description: Allows the user to login using a verification code and token sent via email
parameters:
- in: body
name: email
required: true
type: string
description: The user's email.
- in: body
name: code
required: true
type: string
description: The verification code sent to the email.
- in: body
name: token
name: body
required: true
type: string
description: The token associated with the email code login.
schema:
type: object
required:
- email
- code
- token
properties:
email:
type: string
description: The user's email
code:
type: string
description: The verification code sent to the email
token:
type: string
description: The token associated with the email code login
responses:
200:
description: Successfully logged in, returns token pair data.
description: Successfully logged in
schema:
type: object
properties:
result:
type: string
example: "success"
data:
type: object
description: Token pair data
400:
description: Invalid token, email or code.
description: Invalid token, email or code
"""
parser = reqparse.RequestParser()
parser.add_argument("email", type=str, required=True, location="json")
@ -182,19 +221,38 @@ class RefreshTokenApi(Resource):
def post(self):
"""Refresh authentication token.
---
tags:
- user-end
summary: Refresh Token
description: Refreshes an access token using a valid refresh token.
description: Refreshes an access token using a valid refresh token
security:
- JWT: []
parameters:
- in: body
name: refresh_token
name: body
required: true
type: string
description: The refresh token provided in the request.
schema:
type: object
required:
- refresh_token
properties:
refresh_token:
type: string
description: The refresh token provided in the request
responses:
200:
description: Successfully refreshed token, returns new token pair.
description: Successfully refreshed token
schema:
type: object
properties:
result:
type: string
example: "success"
data:
type: object
description: New token pair data
401:
description: Failed to refresh the token due to invalid or expired refresh token.
description: Unauthorized, invalid or missing token
"""
parser = reqparse.RequestParser()
parser.add_argument("refresh_token", type=str, required=True, location="json")

@ -12,6 +12,7 @@ def init_app(app: DifyApp):
from controllers.inner_api import bp as inner_api_bp
from controllers.service_api import bp as service_api_bp
from controllers.web import bp as web_bp
from controllers.admin import bp as admin_bp
CORS(
service_api_bp,
@ -46,3 +47,10 @@ def init_app(app: DifyApp):
app.register_blueprint(files_bp)
app.register_blueprint(inner_api_bp)
CORS(
admin_bp,
resources={r"/*": {"origins": dify_config.CONSOLE_CORS_ALLOW_ORIGINS}},
supports_credentials=True,
)
app.register_blueprint(admin_bp)

@ -7,7 +7,15 @@ def init_app(app: DifyApp):
app.config['SWAGGER'] = {
'title': 'API Docs',
'uiversion': 3
'uiversion': 3,
'securityDefinitions': {
'JWT': {
'type': 'apiKey',
'name': 'access-token', # name of the cookie
'in': 'header', # specify that auth is in cookie
'description': 'JWT Authorization cookie'
}
}
}
Swagger(app)

Loading…
Cancel
Save