oauth via github

This commit is contained in:
knst-kotov 2021-07-09 07:14:16 +00:00
parent e6b0866f6e
commit 571dad6f60
6 changed files with 76 additions and 31 deletions

View File

@ -6,12 +6,20 @@ from auth.validations import User
class Identity: class Identity:
@staticmethod @staticmethod
def identity(user_id: int, password: str) -> User: def identity(user_id: int, password: str) -> User:
user = global_session.query(OrmUser).filter_by(id=user_id).first() user = global_session.query(OrmUser).filter_by(id=user_id).first()
if not user: if not user:
raise ObjectNotExist("User does not exist") raise ObjectNotExist("User does not exist")
user = User(**user.dict()) user = User(**user.dict())
if not Password.verify(password, user.password): if not Password.verify(password, user.password):
raise InvalidPassword("Wrong user password") raise InvalidPassword("Wrong user password")
return user return user
@staticmethod
def identity_oauth(oauth_id, input) -> User:
user = global_session.query(OrmUser).filter_by(oauth_id=oauth_id).first()
if not user:
user = OrmUser.create(**input)
user = User(**user.dict())
return user

View File

@ -1,28 +1,51 @@
from authlib.integrations.starlette_client import OAuth from authlib.integrations.starlette_client import OAuth
from starlette.responses import PlainTextResponse from starlette.responses import PlainTextResponse
from auth.authorize import Authorize
from auth.identity import Identity
oauth = OAuth() oauth = OAuth()
oauth.register( oauth.register(
name='facebook', name='facebook',
client_id='222122999761250', client_id='222122999761250',
client_secret='', client_secret='',
access_token_url='https://graph.facebook.com/v11.0/oauth/access_token', access_token_url='https://graph.facebook.com/v11.0/oauth/access_token',
access_token_params=None, access_token_params=None,
authorize_url='https://www.facebook.com/v11.0/dialog/oauth', authorize_url='https://www.facebook.com/v11.0/dialog/oauth',
authorize_params=None, authorize_params=None,
api_base_url='https://graph.facebook.com/', api_base_url='https://graph.facebook.com/',
client_kwargs={'scope': 'user:email'}, client_kwargs={'scope': 'user:email'},
)
oauth.register(
name='github',
client_id='58877ba7ad9baef280b4',
client_secret='',
access_token_url='https://github.com/login/oauth/access_token',
access_token_params=None,
authorize_url='https://github.com/login/oauth/authorize',
authorize_params=None,
api_base_url='https://api.github.com/',
client_kwargs={'scope': 'user:email'},
) )
async def oauth_login(request): async def oauth_login(request):
facebook = oauth.create_client('facebook') github = oauth.create_client('github')
redirect_uri = request.url_for('oauth_authorize') redirect_uri = request.url_for('oauth_authorize')
return await facebook.authorize_redirect(request, redirect_uri) return await github.authorize_redirect(request, redirect_uri)
async def oauth_authorize(request): async def oauth_authorize(request):
facebook = oauth.create_client('facebook') github = oauth.create_client('github')
token = await facebook.authorize_access_token(request) token = await github.authorize_access_token(request)
email = await facebook.parse_id_token(request, token) resp = await github.get('user', token=token)
print(email) profile = resp.json()
return PlainTextResponse("%s auth" % email) oauth_id = profile["id"]
user_input = {
"oauth_id" : oauth_id,
"email" : profile["email"],
"username" : profile["name"]
}
user = Identity.identity_oauth(oauth_id=oauth_id, input=user_input)
token = await Authorize.authorize(user, device="pc", auto_delete=False)
return PlainTextResponse(token)

10
create_crt.sh Normal file
View File

@ -0,0 +1,10 @@
#!/bin/bash
openssl req -newkey rsa:4096 \
-x509 \
-sha256 \
-days 3650 \
-nodes \
-out discours.crt \
-keyout discours.key \
-subj "/C=RU/ST=Moscow/L=Moscow/O=Discours/OU=Site/CN=10.0.0.187"

View File

@ -5,6 +5,7 @@ from ariadne.asgi import GraphQL
from starlette.applications import Starlette from starlette.applications import Starlette
from starlette.middleware import Middleware from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.middleware.sessions import SessionMiddleware
from starlette.routing import Route from starlette.routing import Route
from auth.authenticate import JWTAuthenticate from auth.authenticate import JWTAuthenticate
@ -15,8 +16,10 @@ from resolvers.base import resolvers
import_module('resolvers') import_module('resolvers')
schema = make_executable_schema(load_schema_from_path("schema/"), resolvers) schema = make_executable_schema(load_schema_from_path("schema/"), resolvers)
middleware = [Middleware(AuthenticationMiddleware, backend=JWTAuthenticate())] middleware = [
Middleware(AuthenticationMiddleware, backend=JWTAuthenticate()),
Middleware(SessionMiddleware, secret_key="!secret")
]
async def start_up(): async def start_up():
await redis.connect() await redis.connect()
@ -30,6 +33,5 @@ routes = [
Route("/authorize", endpoint=oauth_authorize) Route("/authorize", endpoint=oauth_authorize)
] ]
app = Starlette(debug=True, on_startup=[start_up], on_shutdown=[shutdown], middleware=middleware, routes=routes) app = Starlette(debug=True, on_startup=[start_up], on_shutdown=[shutdown], middleware=middleware, routes=routes)
app.mount("/", GraphQL(schema, debug=True)) app.mount("/", GraphQL(schema, debug=True))

View File

@ -11,9 +11,11 @@ class User(Base):
email: str = Column(String, nullable=False) email: str = Column(String, nullable=False)
username: str = Column(String, nullable=False, comment="Name") username: str = Column(String, nullable=False, comment="Name")
password: str = Column(String, nullable=False, comment="Password") password: str = Column(String, nullable=True, comment="Password")
role_id: int = Column(ForeignKey("role.id"), nullable=True, comment="Role") role_id: int = Column(ForeignKey("role.id"), nullable=True, comment="Role")
oauth_id: str = Column(String, nullable=True)
@classmethod @classmethod
def get_permission(cls, user_id): def get_permission(cls, user_id):

View File

@ -1,4 +1,4 @@
import uvicorn import uvicorn
if __name__ == '__main__': if __name__ == '__main__':
uvicorn.run("main:app", host="0.0.0.0", port=8081, reload=True) uvicorn.run("main:app", host="0.0.0.0", port=8081, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True)