diff --git a/orm/__init__.py b/orm/__init__.py index 8bdfdfc5..a18511a9 100644 --- a/orm/__init__.py +++ b/orm/__init__.py @@ -1,6 +1,6 @@ from orm.rbac import Operation, Resource, Permission, Role from orm.community import Community -from orm.user import User, UserRating +from orm.user import User, UserRating, UserRole from orm.message import Message from orm.topic import Topic, TopicSubscription from orm.notification import Notification diff --git a/orm/user.py b/orm/user.py index 817feb86..73b7af93 100644 --- a/orm/user.py +++ b/orm/user.py @@ -25,11 +25,12 @@ class UserRating(Base): user_id = Column(ForeignKey('user.id'), primary_key = True) value = Column(Integer) -UserRoles = Table("user_roles", - Base.metadata, - Column('user_id', Integer, ForeignKey('user.id'), primary_key = True), - Column('role_id', Integer, ForeignKey('role.id'), primary_key = True) -) +class UserRole(Base): + __tablename__ = "user_role" + + id = None + user_id = Column(ForeignKey('user.id'), primary_key = True) + role_id = Column(ForeignKey('role.id'), primary_key = True) UserTopics = Table("user_topics", Base.metadata, @@ -56,7 +57,7 @@ class User(Base): oauth: str = Column(String, nullable=True) notifications = relationship(lambda: UserNotifications) ratings = relationship(UserRating, foreign_keys=UserRating.user_id) - roles = relationship(lambda: Role, secondary=UserRoles) + roles = relationship(lambda: Role, secondary=UserRole.__tablename__) topics = relationship(lambda: Topic, secondary=UserTopics) old_id: str = Column(String, nullable = True) diff --git a/resolvers/profile.py b/resolvers/profile.py index f54c72dc..bd7e6245 100644 --- a/resolvers/profile.py +++ b/resolvers/profile.py @@ -1,7 +1,9 @@ -from orm import User +from orm import User, UserRole, Role from orm.base import local_session from resolvers.base import mutation, query, subscription from auth.authenticate import login_required + +from sqlalchemy.orm import selectinload import asyncio @query.field("getUserBySlug") # get a public profile @@ -19,3 +21,17 @@ async def get_current_user(_, info): with local_session() as session: user = session.query(User).filter(User.id == user_id).first() return { "user": user } + +@query.field("userRoles") +@login_required +async def user_roles(_, info): + auth = info.context["request"].auth + user_id = auth.user_id + + with local_session() as session: + roles = session.query(Role).\ + options(selectinload(Role.permissions)).\ + join(UserRole).\ + where(UserRole.user_id == user_id).all() + + return roles diff --git a/schema.graphql b/schema.graphql index 179cb1fd..65d25a58 100644 --- a/schema.graphql +++ b/schema.graphql @@ -114,6 +114,7 @@ type Query { getCurrentUser: UserResult! getUserBySlug(slug: String!): UserResult! # rateUser(shout: Int): Int! + userRoles: [Role]! # messages getMessages(count: Int = 100, page: Int = 1): [Message!]! @@ -153,12 +154,27 @@ type Subscription { ############################################ Entities +type Resource { + id: Int! + name: String! +} + +type Operation { + id: Int! + name: String! +} + +type Permission { + operation_id: Int! + resource_id: Int! +} + type Role { id: Int! name: String! community: Int! desc: String - permissions: [Int!]! + permissions: [Permission!]! } type Rating { @@ -192,7 +208,6 @@ type User { links: [String] emailConfirmed: Boolean # should contain all emails too muted: Boolean - roles: [Role] updatedAt: DateTime wasOnlineAt: DateTime rating: Int