add RoleStorage; add mutations for community

This commit is contained in:
knst-kotov 2021-11-24 18:53:01 +03:00
parent 9ab334de71
commit 2d8dc5c3bd
6 changed files with 52 additions and 19 deletions

View File

@ -71,7 +71,7 @@ class JWTAuthenticate(AuthenticationBackend):
return AuthCredentials(scopes=[]), AuthUser(user_id=None) return AuthCredentials(scopes=[]), AuthUser(user_id=None)
user = await UserStorage.get_user(payload.user_id) user = await UserStorage.get_user(payload.user_id)
scopes = user.get_permission() scopes = await user.get_permission()
return AuthCredentials(user_id=payload.user_id, scopes=scopes, logged_in=True), user return AuthCredentials(user_id=payload.user_id, scopes=scopes, logged_in=True), user
class EmailAuthenticate: class EmailAuthenticate:

View File

@ -1,4 +1,4 @@
from orm.rbac import Operation, Resource, Permission, Role from orm.rbac import Operation, Resource, Permission, Role, RoleStorage
from orm.community import Community from orm.community import Community
from orm.user import User, UserRating, UserRole, UserStorage from orm.user import User, UserRating, UserRole, UserStorage
from orm.message import Message from orm.message import Message
@ -18,4 +18,5 @@ Resource.init_table()
with local_session() as session: with local_session() as session:
ShoutRatingStorage.init(session) ShoutRatingStorage.init(session)
ShoutViewStorage.init(session) ShoutViewStorage.init(session)
RoleStorage.init(session)
UserStorage.init(session) UserStorage.init(session)

View File

@ -1,9 +1,10 @@
import warnings import warnings
from typing import Type from typing import Type
import asyncio
from sqlalchemy import String, Integer, Column, ForeignKey, UniqueConstraint, TypeDecorator from sqlalchemy import String, Integer, Column, ForeignKey, UniqueConstraint, TypeDecorator
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship, selectinload
from orm.base import Base, REGISTRY, engine, local_session from orm.base import Base, REGISTRY, engine, local_session
@ -72,6 +73,34 @@ class Permission(Base):
operation_id: int = Column(ForeignKey("operation.id", ondelete="CASCADE"), nullable=False, comment="Operation") operation_id: int = Column(ForeignKey("operation.id", ondelete="CASCADE"), nullable=False, comment="Operation")
resource_id: int = Column(ForeignKey("resource.id", ondelete="CASCADE"), nullable=False, comment="Resource") resource_id: int = Column(ForeignKey("resource.id", ondelete="CASCADE"), nullable=False, comment="Resource")
class RoleStorage:
roles = {}
lock = asyncio.Lock()
@staticmethod
def init(session):
self = RoleStorage
roles = session.query(Role).\
options(selectinload(Role.permissions)).all()
self.roles = dict([(role.id, role) for role in roles])
@staticmethod
async def get_role(id):
self = RoleStorage
async with self.lock:
return self.roles.get(id)
@staticmethod
async def add_role(role):
self = RoleStorage
async with self.lock:
self.roles[id] = role
@staticmethod
async def del_role(id):
self = RoleStorage
async with self.lock:
del self.roles[id]
if __name__ == '__main__': if __name__ == '__main__':
Base.metadata.create_all(engine) Base.metadata.create_all(engine)

View File

@ -4,7 +4,7 @@ from datetime import datetime
from sqlalchemy import Table, Column, Integer, String, ForeignKey, Boolean, DateTime, JSON as JSONType from sqlalchemy import Table, Column, Integer, String, ForeignKey, Boolean, DateTime, JSON as JSONType
from sqlalchemy.orm import relationship, selectinload from sqlalchemy.orm import relationship, selectinload
from orm import Permission from orm import RoleStorage
from orm.base import Base, local_session from orm.base import Base, local_session
from orm.rbac import Role from orm.rbac import Role
from orm.topic import Topic from orm.topic import Topic
@ -63,15 +63,14 @@ class User(Base):
topics = relationship(lambda: Topic, secondary=UserTopics) topics = relationship(lambda: Topic, secondary=UserTopics)
old_id: str = Column(String, nullable = True) old_id: str = Column(String, nullable = True)
@classmethod async def get_permission(self):
def get_permission(self):
scope = {} scope = {}
#TODO implement RoleStorage for user_role in self.roles:
#for role in self.roles: role = await RoleStorage.get_role(user_role.id)
# for p in role.permissions: for p in role.permissions:
# if not p.resource_id in scope: if not p.resource_id in scope:
# scope[p.resource_id] = set() scope[p.resource_id] = set()
# scope[p.resource_id].add(p.operation_id) scope[p.resource_id].add(p.operation_id)
return scope return scope
class UserStorage: class UserStorage:
@ -98,7 +97,7 @@ class UserStorage:
self.users[id] = user self.users[id] = user
@staticmethod @staticmethod
async def del_user(user): async def del_user(id):
self = UserStorage self = UserStorage
async with self.lock: async with self.lock:
del self.users[id] del self.users[id]

View File

@ -56,15 +56,15 @@ async def delete_community(_, info, id):
@query.field("getCommunity") @query.field("getCommunity")
async def get_community(_, info, slug): async def get_community(_, info, slug):
with local_session() as session: with local_session() as session:
community = session.query(Community).filter(Community.slug == slug).first() community = session.query(Community).filter(Community.slug == slug).first()
if not community: if not community:
return {"error": "invalid community id"} return {"error": "invalid community id"}
return { community } return { community }
@query.field("getCommunities") @query.field("getCommunities")
async def get_communities(_, info): async def get_communities(_, info):
with local_session() as session: with local_session() as session:
communities = session.query(Community) communities = session.query(Community)
return { communities } return { communities }

View File

@ -100,6 +100,10 @@ type Mutation {
updateComment(id: Int!, body: String!): CommentResult! updateComment(id: Int!, body: String!): CommentResult!
deleteComment(id: Int!): Result! deleteComment(id: Int!): Result!
rateComment(id: Int!, value: Int!): Result! rateComment(id: Int!, value: Int!): Result!
createCommunity(title: String!, desc: String!): Community!
updateCommunity(id: Int!, title: String!, desc: String!, pic: String!): Community!
deleteCommunity(id: Int!): Result!
} }
################################### Query ################################### Query