Automated deployment: Fri Jan 17 10:44:51 UTC 2020 88b133d41c8c41c56b1ac0dcde1229ed50a5866f

This commit is contained in:
frankie567
2020-01-17 10:44:51 +00:00
parent fef3c96d6a
commit 32484ab513
21 changed files with 1520 additions and 150 deletions

View File

@ -413,6 +413,18 @@
</li>
<li class="md-nav__item">
<a href="/configuration/oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -480,6 +480,18 @@
</li>
<li class="md-nav__item">
<a href="../../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -466,6 +466,18 @@
</li>
<li class="md-nav__item">
<a href="../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -480,6 +480,18 @@
</li>
<li class="md-nav__item">
<a href="../../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -473,6 +473,18 @@
</li>
<li class="md-nav__item">
<a href="../../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -494,6 +494,18 @@
</li>
<li class="md-nav__item">
<a href="../../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -487,6 +487,18 @@
</li>
<li class="md-nav__item">
<a href="../../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -457,6 +457,18 @@
</li>
<li class="md-nav__item">
<a href="../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>
@ -559,80 +571,7 @@
<div class="superfences-tabs">
<input name="__tabs_1" type="radio" id="__tab_1_0" checked="checked" />
<label for="__tab_1_0">SQLAlchemy</label>
<div class="superfences-content"><div class="codehilite"><pre><span></span><span class="kn">import</span> <span class="nn">databases</span>
<span class="kn">import</span> <span class="nn">sqlalchemy</span>
<span class="kn">from</span> <span class="nn">fastapi</span> <span class="kn">import</span> <span class="n">FastAPI</span>
<span class="kn">from</span> <span class="nn">fastapi_users</span> <span class="kn">import</span> <span class="n">FastAPIUsers</span><span class="p">,</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">fastapi_users.authentication</span> <span class="kn">import</span> <span class="n">JWTAuthentication</span>
<span class="kn">from</span> <span class="nn">fastapi_users.db</span> <span class="kn">import</span> <span class="n">SQLAlchemyBaseUserTable</span><span class="p">,</span> <span class="n">SQLAlchemyUserDatabase</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">DeclarativeMeta</span><span class="p">,</span> <span class="n">declarative_base</span>
<span class="n">DATABASE_URL</span> <span class="o">=</span> <span class="s2">&quot;sqlite:///./test.db&quot;</span>
<span class="n">SECRET</span> <span class="o">=</span> <span class="s2">&quot;SECRET&quot;</span>
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">BaseUser</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserCreate</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">BaseUserCreate</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserUpdate</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">BaseUserUpdate</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserDB</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">BaseUserDB</span><span class="p">):</span>
<span class="k">pass</span>
<span class="n">database</span> <span class="o">=</span> <span class="n">databases</span><span class="o">.</span><span class="n">Database</span><span class="p">(</span><span class="n">DATABASE_URL</span><span class="p">)</span>
<span class="n">Base</span><span class="p">:</span> <span class="n">DeclarativeMeta</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">UserTable</span><span class="p">(</span><span class="n">Base</span><span class="p">,</span> <span class="n">SQLAlchemyBaseUserTable</span><span class="p">):</span>
<span class="k">pass</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">create_engine</span><span class="p">(</span>
<span class="n">DATABASE_URL</span><span class="p">,</span> <span class="n">connect_args</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;check_same_thread&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
<span class="p">)</span>
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">UserTable</span><span class="o">.</span><span class="n">__table__</span>
<span class="n">user_db</span> <span class="o">=</span> <span class="n">SQLAlchemyUserDatabase</span><span class="p">(</span><span class="n">UserDB</span><span class="p">,</span> <span class="n">database</span><span class="p">,</span> <span class="n">users</span><span class="p">)</span>
<span class="n">auth_backends</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">JWTAuthentication</span><span class="p">(</span><span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">,</span> <span class="n">lifetime_seconds</span><span class="o">=</span><span class="mi">3600</span><span class="p">),</span>
<span class="p">]</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">FastAPI</span><span class="p">()</span>
<span class="n">fastapi_users</span> <span class="o">=</span> <span class="n">FastAPIUsers</span><span class="p">(</span>
<span class="n">user_db</span><span class="p">,</span> <span class="n">auth_backends</span><span class="p">,</span> <span class="n">User</span><span class="p">,</span> <span class="n">UserCreate</span><span class="p">,</span> <span class="n">UserUpdate</span><span class="p">,</span> <span class="n">UserDB</span><span class="p">,</span> <span class="n">SECRET</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">include_router</span><span class="p">(</span><span class="n">fastapi_users</span><span class="o">.</span><span class="n">router</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;/users&quot;</span><span class="p">,</span> <span class="n">tags</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;users&quot;</span><span class="p">])</span>
<span class="nd">@fastapi_users</span><span class="o">.</span><span class="n">on_after_register</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">on_after_register</span><span class="p">(</span><span class="n">user</span><span class="p">:</span> <span class="n">User</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;User </span><span class="si">{user.id}</span><span class="s2"> has registered.&quot;</span><span class="p">)</span>
<span class="nd">@fastapi_users</span><span class="o">.</span><span class="n">on_after_forgot_password</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">on_after_forgot_password</span><span class="p">(</span><span class="n">user</span><span class="p">:</span> <span class="n">User</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;User </span><span class="si">{user.id}</span><span class="s2"> has forgot their password. Reset token: </span><span class="si">{token}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">on_event</span><span class="p">(</span><span class="s2">&quot;startup&quot;</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">startup</span><span class="p">():</span>
<span class="k">await</span> <span class="n">database</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">on_event</span><span class="p">(</span><span class="s2">&quot;shutdown&quot;</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">shutdown</span><span class="p">():</span>
<span class="k">await</span> <span class="n">database</span><span class="o">.</span><span class="n">disconnect</span><span class="p">()</span>
<div class="superfences-content"><div class="codehilite"><pre><span></span>
</pre></div></div>
<input name="__tabs_1" type="radio" id="__tab_1_1" />
<label for="__tab_1_1">MongoDB</label>
@ -689,58 +628,7 @@
</pre></div></div>
<input name="__tabs_1" type="radio" id="__tab_1_2" />
<label for="__tab_1_2">Tortoise ORM</label>
<div class="superfences-content"><div class="codehilite"><pre><span></span><span class="kn">from</span> <span class="nn">fastapi</span> <span class="kn">import</span> <span class="n">FastAPI</span>
<span class="kn">from</span> <span class="nn">fastapi_users</span> <span class="kn">import</span> <span class="n">FastAPIUsers</span><span class="p">,</span> <span class="n">models</span>
<span class="kn">from</span> <span class="nn">fastapi_users.authentication</span> <span class="kn">import</span> <span class="n">JWTAuthentication</span>
<span class="kn">from</span> <span class="nn">fastapi_users.db</span> <span class="kn">import</span> <span class="n">TortoiseBaseUserModel</span><span class="p">,</span> <span class="n">TortoiseUserDatabase</span>
<span class="kn">from</span> <span class="nn">tortoise.contrib.starlette</span> <span class="kn">import</span> <span class="n">register_tortoise</span>
<span class="n">DATABASE_URL</span> <span class="o">=</span> <span class="s2">&quot;sqlite://./test.db&quot;</span>
<span class="n">SECRET</span> <span class="o">=</span> <span class="s2">&quot;SECRET&quot;</span>
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">BaseUser</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserCreate</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">BaseUserCreate</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserUpdate</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">BaseUserUpdate</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserDB</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">BaseUserDB</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">UserModel</span><span class="p">(</span><span class="n">TortoiseBaseUserModel</span><span class="p">):</span>
<span class="k">pass</span>
<span class="n">user_db</span> <span class="o">=</span> <span class="n">TortoiseUserDatabase</span><span class="p">(</span><span class="n">UserDB</span><span class="p">,</span> <span class="n">UserModel</span><span class="p">)</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">FastAPI</span><span class="p">()</span>
<span class="n">register_tortoise</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">db_url</span><span class="o">=</span><span class="n">DATABASE_URL</span><span class="p">,</span> <span class="n">modules</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;models&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;test&quot;</span><span class="p">]})</span>
<span class="n">auth_backends</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">JWTAuthentication</span><span class="p">(</span><span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">,</span> <span class="n">lifetime_seconds</span><span class="o">=</span><span class="mi">3600</span><span class="p">),</span>
<span class="p">]</span>
<span class="n">fastapi_users</span> <span class="o">=</span> <span class="n">FastAPIUsers</span><span class="p">(</span>
<span class="n">user_db</span><span class="p">,</span> <span class="n">auth_backends</span><span class="p">,</span> <span class="n">User</span><span class="p">,</span> <span class="n">UserCreate</span><span class="p">,</span> <span class="n">UserUpdate</span><span class="p">,</span> <span class="n">UserDB</span><span class="p">,</span> <span class="n">SECRET</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">include_router</span><span class="p">(</span><span class="n">fastapi_users</span><span class="o">.</span><span class="n">router</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;/users&quot;</span><span class="p">,</span> <span class="n">tags</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;users&quot;</span><span class="p">])</span>
<span class="nd">@fastapi_users</span><span class="o">.</span><span class="n">on_after_register</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">on_after_register</span><span class="p">(</span><span class="n">user</span><span class="p">:</span> <span class="n">User</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;User </span><span class="si">{user.id}</span><span class="s2"> has registered.&quot;</span><span class="p">)</span>
<span class="nd">@fastapi_users</span><span class="o">.</span><span class="n">on_after_forgot_password</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">on_after_forgot_password</span><span class="p">(</span><span class="n">user</span><span class="p">:</span> <span class="n">User</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;User </span><span class="si">{user.id}</span><span class="s2"> has forgot their password. Reset token: </span><span class="si">{token}</span><span class="s2">&quot;</span><span class="p">)</span>
<div class="superfences-content"><div class="codehilite"><pre><span></span>
</pre></div></div>
</div>
<h2 id="what-now">What now?<a class="headerlink" href="#what-now" title="Permanent link">&para;</a></h2>
@ -781,13 +669,13 @@
</a>
<a href="../../usage/routes/" title="Routes" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<a href="../oauth/" title="OAuth2" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Routes
OAuth2
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">

View File

@ -464,6 +464,18 @@
</li>
<li class="md-nav__item">
<a href="../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

File diff suppressed because it is too large Load Diff

View File

@ -491,6 +491,18 @@
</li>
<li class="md-nav__item">
<a href="../oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -496,6 +496,18 @@
</li>
<li class="md-nav__item">
<a href="configuration/oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -469,6 +469,18 @@
</li>
<li class="md-nav__item">
<a href="../configuration/oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

File diff suppressed because one or more lines are too long

View File

@ -2,67 +2,72 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-15</lastmod>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None</loc>
<lastmod>2020-01-17</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

Binary file not shown.

57
src/oauth_full_mongodb.py Normal file
View File

@ -0,0 +1,57 @@
import motor.motor_asyncio
from fastapi import FastAPI
from fastapi_users import FastAPIUsers, models
from fastapi_users.authentication import JWTAuthentication
from fastapi_users.db import MongoDBUserDatabase
from httpx_oauth.clients.google import GoogleOAuth2
DATABASE_URL = "mongodb://localhost:27017"
SECRET = "SECRET"
google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
class User(models.BaseUser, models.BaseOAuthAccountMixin):
pass
class UserCreate(User, models.BaseUserCreate):
pass
class UserUpdate(User, models.BaseUserUpdate):
pass
class UserDB(User, models.BaseUserDB):
pass
client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL)
db = client["database_name"]
collection = db["users"]
user_db = MongoDBUserDatabase(UserDB, collection)
auth_backends = [
JWTAuthentication(secret=SECRET, lifetime_seconds=3600),
]
app = FastAPI()
fastapi_users = FastAPIUsers(
user_db, auth_backends, User, UserCreate, UserUpdate, UserDB, SECRET,
)
app.include_router(fastapi_users.router, prefix="/users", tags=["users"])
google_oauth_router = fastapi_users.get_oauth_router(google_oauth_client, SECRET)
app.include_router(google_oauth_router, prefix="/google-oauth", tags=["users"])
@fastapi_users.on_after_register()
def on_after_register(user: User):
print(f"User {user.id} has registered.")
@fastapi_users.on_after_forgot_password()
def on_after_forgot_password(user: User, token: str):
print(f"User {user.id} has forgot their password. Reset token: {token}")

View File

@ -3,14 +3,22 @@ import sqlalchemy
from fastapi import FastAPI
from fastapi_users import FastAPIUsers, models
from fastapi_users.authentication import JWTAuthentication
from fastapi_users.db import SQLAlchemyBaseUserTable, SQLAlchemyUserDatabase
from fastapi_users.db import (
SQLAlchemyBaseOAuthAccountTable,
SQLAlchemyBaseUserTable,
SQLAlchemyUserDatabase,
)
from httpx_oauth.clients.google import GoogleOAuth2
from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
DATABASE_URL = "sqlite:///./test.db"
SECRET = "SECRET"
class User(models.BaseUser):
google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
class User(models.BaseUser, models.BaseOAuthAccountMixin):
pass
@ -34,13 +42,18 @@ class UserTable(Base, SQLAlchemyBaseUserTable):
pass
class OAuthAccount(SQLAlchemyBaseOAuthAccountTable, Base):
pass
engine = sqlalchemy.create_engine(
DATABASE_URL, connect_args={"check_same_thread": False}
)
Base.metadata.create_all(engine)
users = UserTable.__table__
user_db = SQLAlchemyUserDatabase(UserDB, database, users)
oauth_accounts = OAuthAccount.__table__
user_db = SQLAlchemyUserDatabase(UserDB, database, users, oauth_accounts)
auth_backends = [
@ -53,6 +66,9 @@ fastapi_users = FastAPIUsers(
)
app.include_router(fastapi_users.router, prefix="/users", tags=["users"])
google_oauth_router = fastapi_users.get_oauth_router(google_oauth_client, SECRET)
app.include_router(google_oauth_router, prefix="/google-oauth", tags=["users"])
@fastapi_users.on_after_register()
def on_after_register(user: User):

View File

@ -1,14 +1,23 @@
from fastapi import FastAPI
from fastapi_users import FastAPIUsers, models
from fastapi_users.authentication import JWTAuthentication
from fastapi_users.db import TortoiseBaseUserModel, TortoiseUserDatabase
from fastapi_users.db import (
TortoiseBaseOAuthAccountModel,
TortoiseBaseUserModel,
TortoiseUserDatabase,
)
from httpx_oauth.clients.google import GoogleOAuth2
from tortoise import fields
from tortoise.contrib.starlette import register_tortoise
DATABASE_URL = "sqlite://./test.db"
SECRET = "SECRET"
class User(models.BaseUser):
google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
class User(models.BaseUser, models.BaseOAuthAccountMixin):
pass
@ -28,7 +37,11 @@ class UserModel(TortoiseBaseUserModel):
pass
user_db = TortoiseUserDatabase(UserDB, UserModel)
class OAuthAccountModel(TortoiseBaseOAuthAccountModel):
user = fields.ForeignKeyField("models.UserModel", related_name="oauth_accounts")
user_db = TortoiseUserDatabase(UserDB, UserModel, OAuthAccountModel)
app = FastAPI()
register_tortoise(app, db_url=DATABASE_URL, modules={"models": ["test"]})
@ -41,6 +54,9 @@ fastapi_users = FastAPIUsers(
)
app.include_router(fastapi_users.router, prefix="/users", tags=["users"])
google_oauth_router = fastapi_users.get_oauth_router(google_oauth_client, SECRET)
app.include_router(google_oauth_router, prefix="/google-oauth", tags=["users"])
@fastapi_users.on_after_register()
def on_after_register(user: User):

View File

@ -417,6 +417,18 @@
</li>
<li class="md-nav__item">
<a href="../../configuration/oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>

View File

@ -417,6 +417,18 @@
</li>
<li class="md-nav__item">
<a href="../../configuration/oauth/" title="OAuth2" class="md-nav__link">
OAuth2
</a>
</li>
</ul>
</nav>
</li>
@ -509,6 +521,33 @@
POST /reset-password
</a>
</li>
<li class="md-nav__item">
<a href="#oauth-routes" class="md-nav__link">
OAuth routes
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get-authorize" class="md-nav__link">
GET /authorize
</a>
</li>
<li class="md-nav__item">
<a href="#get-callback" class="md-nav__link">
GET /callback
</a>
</li>
</ul>
</nav>
</li>
</ul>
@ -666,6 +705,33 @@
POST /reset-password
</a>
</li>
<li class="md-nav__item">
<a href="#oauth-routes" class="md-nav__link">
OAuth routes
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#get-authorize" class="md-nav__link">
GET /authorize
</a>
</li>
<li class="md-nav__item">
<a href="#get-callback" class="md-nav__link">
GET /callback
</a>
</li>
</ul>
</nav>
</li>
</ul>
@ -855,6 +921,60 @@
</pre></div>
</div>
<h3 id="oauth-routes">OAuth routes<a class="headerlink" href="#oauth-routes" title="Permanent link">&para;</a></h3>
<p>Each OAuth router you define will expose the two following routes.</p>
<h4 id="get-authorize"><code>GET /authorize</code><a class="headerlink" href="#get-authorize" title="Permanent link">&para;</a></h4>
<p>Return the authorization URL for the OAuth service where you should redirect your user.</p>
<div class="admonition abstract">
<p class="admonition-title">Query parameters</p>
<ul>
<li><code>authentication_backend</code>: Name of a defined <a href="../../configuration/authentication/">authentication method</a> to use to authenticate the user on successful callback.</li>
<li><code>scopes</code>: Optional list of scopes to ask for. Expected format: <code>scopes=a&amp;scopes=b</code>.</li>
</ul>
</div>
<div class="admonition success">
<p class="admonition-title"><code>200 OK</code></p>
<div class="codehilite"><pre><span></span><span class="p">{</span>
<span class="nt">&quot;authorization_url&quot;</span><span class="p">:</span> <span class="s2">&quot;https://www.tintagel.bt/oauth/authorize?client_id=CLIENT_ID&amp;scopes=a+b&amp;redirect_uri=https://www.camelot.bt/oauth/callback&quot;</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition fail">
<p class="admonition-title"><code>422 Validation Error</code></p>
</div>
<div class="admonition fail">
<p class="admonition-title"><code>400 Bad Request</code></p>
<p>Unknown authentication backend.</p>
</div>
<h4 id="get-callback"><code>GET /callback</code><a class="headerlink" href="#get-callback" title="Permanent link">&para;</a></h4>
<p>Handle the OAuth callback.</p>
<div class="admonition abstract">
<p class="admonition-title">Query parameters</p>
<ul>
<li><code>code</code>: OAuth callback code.</li>
<li><code>state</code>: State token.</li>
<li><code>error</code>: OAuth error.</li>
</ul>
</div>
<p>Depending on the situation, several things can happen:</p>
<ul>
<li>The OAuth account exists in database and is linked to a user:<ul>
<li>OAuth account is updated in database with fresh access token.</li>
<li>The user is authenticated following the chosen <a href="../../configuration/authentication/">authentication method</a>.</li>
</ul>
</li>
<li>The OAuth account doesn't exist in database but a user with the same email address exists:<ul>
<li>OAuth account is linked to the user.</li>
<li>The user is authenticated following the chosen <a href="../../configuration/authentication/">authentication method</a>.</li>
</ul>
</li>
<li>The OAuth account doesn't exist in database and no user with the email address exists:<ul>
<li>A new user is created and linked to the OAuth account.</li>
<li>The user is authenticated following the chosen <a href="../../configuration/authentication/">authentication method</a>.</li>
</ul>
</li>
</ul>
<h2 id="authenticated">Authenticated<a class="headerlink" href="#authenticated" title="Permanent link">&para;</a></h2>
<h3 id="get-me"><code>GET /me</code><a class="headerlink" href="#get-me" title="Permanent link">&para;</a></h3>
<p>Return the current authenticated active user.</p>
@ -1020,7 +1140,7 @@
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../../configuration/full_example/" title="Full example" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<a href="../../configuration/oauth/" title="OAuth2" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
@ -1029,7 +1149,7 @@
<span class="md-footer-nav__direction">
Previous
</span>
Full example
OAuth2
</span>
</div>
</a>