update docs

This commit is contained in:
long2ice
2021-04-29 18:45:21 +08:00
parent 20c4a6bdd1
commit 0178386f44
12 changed files with 49 additions and 28 deletions

View File

@@ -1 +0,0 @@
../../../../README.md

View File

@@ -1,4 +1,4 @@
# Quickstart
# Quick Start
`FastAPI-Admin` is easy to mount your `FastAPI` app, just need a few configs.

View File

@@ -4,7 +4,7 @@
You can set captcha in admin login page, just set `enable_captcha=True`.
```python
```python3
login_provider = UsernamePasswordProvider(user_model=User, enable_captcha=True)
```
@@ -13,9 +13,11 @@ login_provider = UsernamePasswordProvider(user_model=User, enable_captcha=True)
If you want limit login failed ip with error password, you can use `LoginPasswordMaxTryMiddleware`.
```python
admin_app.add_middleware(BaseHTTPMiddleware, dispatch=LoginPasswordMaxTryMiddleware(max_times = 3, after_seconds = 360))
admin_app.add_middleware(BaseHTTPMiddleware, dispatch=LoginPasswordMaxTryMiddleware(max_times=3, after_seconds=360))
```
## Permission Control
## Additional File Upload Providers
### ALiYunOSSProvider
@@ -54,6 +56,9 @@ If your site is in maintenance, you can set `true` to `admin_app.configure(...)`
admin_app.configure(maintenance=True)
```
## Admin Log
## Free consultation
Whenever you have any questions, you can send email to <long2ice@gmai.com> or open `issue` in `fastapi-admin-pro` repository, I will answer your questions as soon as possible.
Whenever you have any questions, you can send email to <long2ice@gmai.com> or open `issue` in `fastapi-admin-pro`
repository, I will answer your questions as soon as possible.

View File

@@ -0,0 +1 @@
# Admin Log (💗 Pro only)

View File

@@ -1,3 +1,11 @@
# Middleware
## LoginPasswordMaxTryMiddleware (💗 Pro only)
If you want limit login failed ip with error password, you can use `LoginPasswordMaxTryMiddleware`.
```python
admin_app.add_middleware(BaseHTTPMiddleware, dispatch=LoginPasswordMaxTryMiddleware(max_times=3, after_seconds=3600))
```
After that, user can try max `3` times password, if all failed, the ip will be limited `3600` seconds.

View File

@@ -0,0 +1 @@
# Permission Control (💗 Pro only)

View File

@@ -35,10 +35,10 @@ markdown_extensions:
- pymdownx.inlinehilite
- pymdownx.superfences
nav:
- Home: index.md
- Getting Started:
- getting_started/index.md
- getting_started/installation.md
- getting_started/quickstart.md
- getting_started/quick_start.md
- Reference:
- reference/configuration.md
- reference/resource.md
@@ -48,6 +48,8 @@ nav:
- reference/widget/input.md
- reference/file_upload.md
- reference/middleware.md
- reference/permission.md
- reference/admin_log.md
- Custom:
- custom/page.md
- custom/overwrite.md

View File

@@ -1 +0,0 @@
../../../../README.md

View File

@@ -35,8 +35,8 @@ markdown_extensions:
- pymdownx.inlinehilite
- pymdownx.superfences
nav:
- 首页: index.md
- 入门指南:
- getting_started/index.md
- getting_started/installation.md
- getting_started/quickstart.md
- 参考:

View File

@@ -3,6 +3,8 @@ import os
import aioredis
import uvicorn
from fastapi import FastAPI
from fastapi_admin.app import app as admin_app
from fastapi_admin.providers.login import UsernamePasswordProvider
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import RedirectResponse
from starlette.staticfiles import StaticFiles
@@ -11,8 +13,6 @@ from tortoise.contrib.fastapi import register_tortoise
from examples import settings
from examples.constants import BASE_DIR
from examples.models import User
from fastapi_admin.app import app as admin_app
from fastapi_admin.providers.login import UsernamePasswordProvider
login_provider = UsernamePasswordProvider(user_model=User)

View File

@@ -1,17 +1,15 @@
import datetime
from fastapi_admin.providers.login import AbstractUser
from tortoise import Model, fields
from examples.enums import Action, ProductType, Status
from fastapi_admin.providers.login import UserMixin
class User(UserMixin):
is_active = fields.BooleanField(
default=True,
class User(AbstractUser):
last_login = fields.DatetimeField(
description="Last Login", default=datetime.datetime.now
)
is_superuser = fields.BooleanField(default=False)
last_login = fields.DatetimeField(description="Last Login", default=datetime.datetime.now)
avatar = fields.CharField(max_length=200, default="")
intro = fields.TextField(default="")
created_at = fields.DatetimeField(auto_now_add=True)
@@ -40,7 +38,9 @@ class Product(Model):
class Config(Model):
label = fields.CharField(max_length=200)
key = fields.CharField(max_length=20, unique=True, description="Unique key for config")
key = fields.CharField(
max_length=20, unique=True, description="Unique key for config"
)
value = fields.JSONField()
status: Status = fields.IntEnumField(Status, default=Status.on)

View File

@@ -5,19 +5,20 @@ from typing import Callable, Type
import bcrypt
from aioredis import Redis
from fastapi import Depends
from fastapi_admin import constants
from fastapi_admin.depends import get_redis
from fastapi_admin.template import templates
from pydantic import EmailStr
from starlette.requests import Request
from starlette.responses import RedirectResponse
from starlette.status import HTTP_303_SEE_OTHER, HTTP_401_UNAUTHORIZED
from tortoise import Model, fields
from fastapi_admin import constants
from fastapi_admin.depends import get_redis
from fastapi_admin.template import templates
class LoginProvider:
def __init__(self, login_path="/login", logout_path="/logout", template="login.html"):
def __init__(
self, login_path="/login", logout_path="/logout", template="login.html"
):
self.template = template
self.logout_path = logout_path
self.login_path = login_path
@@ -55,9 +56,8 @@ class LoginProvider:
return self.redirect_login(request)
class UserMixin(Model):
class AbstractUser(Model):
username = fields.CharField(max_length=50, unique=True)
email = fields.CharField(max_length=50, unique=True)
password = fields.CharField(max_length=200)
class Meta:
@@ -90,7 +90,9 @@ class UsernamePasswordProvider(LoginProvider):
status_code=HTTP_401_UNAUTHORIZED,
context={"request": request, "error": _("login_failed")},
)
response = RedirectResponse(url=request.app.admin_path, status_code=HTTP_303_SEE_OTHER)
response = RedirectResponse(
url=request.app.admin_path, status_code=HTTP_303_SEE_OTHER
)
if remember_me == "on":
expire = 3600 * 24 * 30
response.set_cookie("remember_me", "on")
@@ -105,7 +107,9 @@ class UsernamePasswordProvider(LoginProvider):
path=request.app.admin_path,
httponly=True,
)
await redis.set(constants.LOGIN_USER.format(token=token), user.pk, expire=expire)
await redis.set(
constants.LOGIN_USER.format(token=token), user.pk, expire=expire
)
return response
async def logout(self, request: Request, redis: Redis = Depends(get_redis)):
@@ -135,7 +139,9 @@ class UsernamePasswordProvider(LoginProvider):
return response
else:
if path == self.login_path:
return RedirectResponse(url=request.app.admin_path, status_code=HTTP_303_SEE_OTHER)
return RedirectResponse(
url=request.app.admin_path, status_code=HTTP_303_SEE_OTHER
)
request.state.user = user
response = await call_next(request)