Merge branch 'main' of github.com:Discours/discours-backend into viewed
This commit is contained in:
commit
3f51515c5c
|
@ -7,7 +7,7 @@ Tech stack:
|
|||
- ariadne
|
||||
- starlette
|
||||
|
||||
# Local development
|
||||
# Local development
|
||||
|
||||
Install deps first
|
||||
|
||||
|
@ -40,5 +40,5 @@ python3 server.py dev
|
|||
|
||||
# How to do an authorized request
|
||||
|
||||
Put the header 'Auth' with token from signInQuery or registerQuery.
|
||||
Put the header 'Authorization' with token from signInQuery or registerQuery.
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from auth.jwtcodec import JWTCodec
|
|||
from auth.tokenstorage import TokenStorage
|
||||
from base.exceptions import InvalidToken
|
||||
from services.auth.users import UserStorage
|
||||
from settings import SESSION_TOKEN_HEADER
|
||||
|
||||
|
||||
class SessionToken:
|
||||
|
@ -48,10 +49,12 @@ class JWTAuthenticate(AuthenticationBackend):
|
|||
async def authenticate(
|
||||
self, request: HTTPConnection
|
||||
) -> Optional[Tuple[AuthCredentials, AuthUser]]:
|
||||
if "Auth" not in request.headers:
|
||||
|
||||
if SESSION_TOKEN_HEADER not in request.headers:
|
||||
return AuthCredentials(scopes=[]), AuthUser(user_id=None)
|
||||
|
||||
token = request.headers.get("Auth", "")
|
||||
token = request.headers.get(SESSION_TOKEN_HEADER, "")
|
||||
|
||||
try:
|
||||
payload = await SessionToken.verify(token)
|
||||
except Exception as exc:
|
||||
|
|
|
@ -25,6 +25,8 @@ async def send_auth_email(user, token, lang="ru"):
|
|||
"h:X-Mailgun-Variables": "{ \"token\": \"%s\" }" % token
|
||||
}
|
||||
print('[auth.email] payload: %r' % payload)
|
||||
# debug
|
||||
# print('http://localhost:3000/?modal=auth&mode=confirm-email&token=%s' % token)
|
||||
response = requests.post(
|
||||
api_url,
|
||||
auth=("api", MAILGUN_API_KEY),
|
||||
|
|
|
@ -119,7 +119,7 @@ server {
|
|||
#
|
||||
# Custom headers and headers various browsers *should* be OK with but aren't
|
||||
#
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Auth';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
#
|
||||
# Tell client that this pre-flight info is valid for 20 days
|
||||
|
@ -133,7 +133,7 @@ server {
|
|||
if ($request_method = 'POST') {
|
||||
add_header 'Access-Control-Allow-Origin' '$allow_origin' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Auth' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ server {
|
|||
if ($request_method = 'GET') {
|
||||
add_header 'Access-Control-Allow-Origin' '$allow_origin' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Auth' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ from base.orm import local_session
|
|||
from base.resolvers import mutation, query
|
||||
from orm import Role, User
|
||||
from resolvers.zine.profile import user_subscriptions
|
||||
from settings import SESSION_TOKEN_HEADER
|
||||
|
||||
|
||||
@mutation.field("refreshSession")
|
||||
|
@ -143,7 +144,6 @@ async def auth_send_link(_, _info, email, lang="ru"):
|
|||
|
||||
@query.field("signIn")
|
||||
async def login(_, info, email: str, password: str = "", lang: str = "ru"):
|
||||
|
||||
with local_session() as session:
|
||||
orm_user = session.query(User).filter(User.email == email).first()
|
||||
if orm_user is None:
|
||||
|
@ -182,7 +182,7 @@ async def login(_, info, email: str, password: str = "", lang: str = "ru"):
|
|||
@query.field("signOut")
|
||||
@login_required
|
||||
async def sign_out(_, info: GraphQLResolveInfo):
|
||||
token = info.context["request"].headers.get("Auth", "")
|
||||
token = info.context["request"].headers.get(SESSION_TOKEN_HEADER, "")
|
||||
status = await TokenStorage.revoke(token)
|
||||
return status
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ from services.zine.shoutauthor import ShoutAuthorStorage
|
|||
from services.stat.reacted import ReactedStorage
|
||||
|
||||
|
||||
def apply_filters(filters, q, user=None):
|
||||
def apply_filters(q, filters, user=None):
|
||||
filters = {} if filters is None else filters
|
||||
if filters.get("reacted") and user:
|
||||
q.join(Reaction, Reaction.createdBy == user.slug)
|
||||
if filters.get("visibility"):
|
||||
|
@ -106,7 +107,7 @@ async def load_shouts_by(_, info, options):
|
|||
Shout.deletedAt.is_(None)
|
||||
)
|
||||
user = info.context["request"].user
|
||||
q = apply_filters(options.get("filters"), q, user)
|
||||
q = apply_filters(q, options.get("filters"), user)
|
||||
|
||||
order_by = extract_order(options.get("order_by"), q)
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ if __name__ == "__main__":
|
|||
("Access-Control-Allow-Origin", "http://localhost:3000"),
|
||||
(
|
||||
"Access-Control-Allow-Headers",
|
||||
"DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Auth",
|
||||
"DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization",
|
||||
),
|
||||
("Access-Control-Expose-Headers", "Content-Length,Content-Range"),
|
||||
("Access-Control-Allow-Credentials", "true"),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import asyncio
|
||||
from sqlalchemy.orm import selectinload
|
||||
from orm.user import User
|
||||
from base.orm import local_session
|
||||
|
||||
|
||||
class UserStorage:
|
||||
|
@ -20,9 +21,15 @@ class UserStorage:
|
|||
|
||||
@staticmethod
|
||||
async def get_user(id):
|
||||
self = UserStorage
|
||||
async with self.lock:
|
||||
return self.users.get(id)
|
||||
with local_session() as session:
|
||||
user = (
|
||||
session.query(User)
|
||||
.options(selectinload(User.roles), selectinload(User.ratings))
|
||||
.filter(User.id == id)
|
||||
.one()
|
||||
)
|
||||
|
||||
return user
|
||||
|
||||
@staticmethod
|
||||
async def get_all_users():
|
||||
|
|
|
@ -36,7 +36,8 @@ class ReactedStorage:
|
|||
@staticmethod
|
||||
async def get_shout_stat(slug):
|
||||
return {
|
||||
"viewed": await ViewedStorage.get_shout(slug),
|
||||
# TODO
|
||||
"viewed": 0, # await ViewedStorage.get_shout(slug),
|
||||
"reacted": len(await ReactedStorage.get_shout(slug)),
|
||||
"commented": len(await ReactedStorage.get_comments(slug)),
|
||||
"rating": await ReactedStorage.get_rating(slug),
|
||||
|
|
|
@ -24,3 +24,4 @@ for provider in OAUTH_PROVIDERS:
|
|||
}
|
||||
|
||||
SHOUTS_REPO = "content"
|
||||
SESSION_TOKEN_HEADER = "Authorization"
|
||||
|
|
Loading…
Reference in New Issue
Block a user