Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion freenit/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.3.11"
__version__ = "0.3.12"
8 changes: 3 additions & 5 deletions freenit/api/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from freenit.config import getConfig
from freenit.mail import sendmail
from freenit.models.user import User
from freenit.models.safe import UserSafe

config = getConfig()

Expand All @@ -23,7 +24,7 @@ class TokenExpire(pydantic.BaseModel):


class LoginResponse(pydantic.BaseModel):
user: User
user: UserSafe
expire: TokenExpire


Expand All @@ -48,7 +49,6 @@ async def login(credentials: LoginInput, response: Response):
httponly=True,
secure=config.auth.secure,
)
user.password = None
return {
"user": user,
"expire": {
Expand Down Expand Up @@ -78,7 +78,6 @@ async def register_sql(credentials: LoginInput) -> User:
active=False,
)
await user.save()
user.password = None
return user


Expand Down Expand Up @@ -106,7 +105,7 @@ async def register(credentials: LoginInput, host=Header(default="")):
return {"status": True}


@api.post("/auth/verify", response_model=User, tags=["auth"])
@api.post("/auth/verify", response_model=UserSafe, tags=["auth"])
async def verify(verification: Verification):
user = await decode(verification.verification)
await user.update(active=True)
Expand All @@ -118,7 +117,6 @@ async def refresh(request: Request, response: Response):
user = await authorize(request, cookie="refresh")
access = encode(user)
response.set_cookie("access", access, httponly=True, secure=config.auth.secure)
user.password = None
return {
"user": user,
"expire": {
Expand Down
41 changes: 17 additions & 24 deletions freenit/api/role/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from freenit.decorators import description
from freenit.models.pagination import Page, paginate
from freenit.models.role import Role, RoleOptional
from freenit.models.safe import RoleSafe, UserSafe
from freenit.models.user import User
from freenit.permissions import role_perms

Expand All @@ -20,49 +21,49 @@ async def get(
page: int = Header(default=1),
perpage: int = Header(default=10),
_: User = Depends(role_perms),
) -> Page[Role]:
return await paginate(
Role.objects.select_related("users").exclude_fields("users__password"),
) -> Page[RoleSafe]:
ret = await paginate(
Role.objects.select_related("users"),
page,
perpage,
)
return ret

@staticmethod
async def post(role: Role, _: User = Depends(role_perms)) -> Role:
async def post(role: Role, _: User = Depends(role_perms)) -> RoleSafe:
await role.save()
await role.load_all()
return role


@route("/roles/{id}", tags=tags)
class RoleDetailAPI:
@staticmethod
async def get(id, _: User = Depends(role_perms)) -> Role:
async def get(id, _: User = Depends(role_perms)) -> RoleSafe:
try:
role = (
await Role.objects.select_related("users")
.exclude_fields("users__password")
.get(pk=id)
)
role = await Role.objects.select_related("users").get(pk=id)
except ormar.exceptions.NoMatch:
raise HTTPException(status_code=404, detail="No such role")
await role.load_all()
return role

@staticmethod
async def patch(id, role_data: RoleOptional, _: User = Depends(role_perms)) -> Role:
async def patch(id, role_data: RoleOptional, _: User = Depends(role_perms)) -> RoleSafe:
if Role.dbtype() == "sql":
try:
role = await Role.objects.get(pk=id)
except ormar.exceptions.NoMatch:
raise HTTPException(status_code=404, detail="No such role")
await role.patch(role_data)
await role.load_all()
return role
raise HTTPException(
status_code=409,
detail=f"Role type {Role.dbtype()} doesn't support PATCH method",
)

@staticmethod
async def delete(id, _: User = Depends(role_perms)) -> Role:
async def delete(id, _: User = Depends(role_perms)) -> RoleSafe:
try:
role = await Role.objects.get(pk=id)
except ormar.exceptions.NoMatch:
Expand All @@ -75,13 +76,9 @@ async def delete(id, _: User = Depends(role_perms)) -> Role:
class RoleUserAPI:
@staticmethod
@description("Assign user to role")
async def post(role_id, user_id, _: User = Depends(role_perms)) -> User:
async def post(role_id, user_id, _: User = Depends(role_perms)) -> UserSafe:
try:
user = (
await User.objects.select_related("roles")
.exclude_fields("password")
.get(pk=user_id)
)
user = await User.objects.select_related("roles").get(pk=user_id)
except ormar.exceptions.NoMatch:
raise HTTPException(status_code=404, detail="No such user")
for role in user.roles:
Expand All @@ -96,13 +93,9 @@ async def post(role_id, user_id, _: User = Depends(role_perms)) -> User:

@staticmethod
@description("Deassign user to role")
async def delete(role_id, user_id, _: User = Depends(role_perms)) -> User:
async def delete(role_id, user_id, _: User = Depends(role_perms)) -> UserSafe:
try:
user = (
await User.objects.select_related("roles")
.exclude_fields("password")
.get(pk=user_id)
)
user = await User.objects.select_related("roles").get(pk=user_id)
except ormar.exceptions.NoMatch:
raise HTTPException(status_code=404, detail="No such user")
try:
Expand Down
23 changes: 9 additions & 14 deletions freenit/api/user/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from freenit.decorators import description
from freenit.models.pagination import Page, paginate
from freenit.models.user import User, UserOptional
from freenit.models.safe import UserSafe
from freenit.permissions import profile_perms, user_perms

tags = ["user"]
Expand All @@ -23,9 +24,9 @@ async def get(
page: int = Header(default=1),
perpage: int = Header(default=10),
_: User = Depends(user_perms),
) -> Page[User]:
) -> Page[UserSafe]:
return await paginate(
User.objects.select_related("roles").exclude_fields("password"),
User.objects.select_related(["roles"]),
page,
perpage,
)
Expand All @@ -34,19 +35,15 @@ async def get(
@route("/users/{id}", tags=tags)
class UserDetailAPI:
@staticmethod
async def get(id, _: User = Depends(user_perms)) -> User:
async def get(id, _: User = Depends(user_perms)) -> UserSafe:
try:
user = (
await User.objects.select_related("roles")
.exclude_fields("password")
.get(pk=id)
)
user = await User.objects.select_related("roles").get(pk=id)
except ormar.exceptions.NoMatch:
raise HTTPException(status_code=404, detail="No such user")
return user

@staticmethod
async def patch(id, data: UserOptional, _: User = Depends(user_perms)) -> User:
async def patch(id, data: UserOptional, _: User = Depends(user_perms)) -> UserSafe:
if data.password:
data.password = encrypt(data.password)
try:
Expand All @@ -57,7 +54,7 @@ async def patch(id, data: UserOptional, _: User = Depends(user_perms)) -> User:
return user

@staticmethod
async def delete(id, _: User = Depends(user_perms)) -> User:
async def delete(id, _: User = Depends(user_perms)) -> UserSafe:
try:
user = await User.objects.get(pk=id)
except ormar.exceptions.NoMatch:
Expand All @@ -70,15 +67,13 @@ async def delete(id, _: User = Depends(user_perms)) -> User:
class ProfileDetailAPI:
@staticmethod
@description("Get my profile")
async def get(user: User = Depends(profile_perms)) -> User:
async def get(user: User = Depends(profile_perms)) -> UserSafe:
await user.load_all()
return user

@staticmethod
@description("Edit my profile")
async def patch(
data: UserOptional, user: User = Depends(profile_perms)
) -> User:
async def patch(data: UserOptional, user: User = Depends(profile_perms)) -> UserSafe:
if data.password:
data.password = encrypt(data.password)
await user.patch(data)
Expand Down
10 changes: 8 additions & 2 deletions freenit/models/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@

config = getConfig()
auth = config.get_model("role")
Role = auth.Role
RoleOptional = auth.RoleOptional


class Role(auth.Role):
pass


class RoleOptional(auth.RoleOptional):
pass
13 changes: 13 additions & 0 deletions freenit/models/safe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import List

from freenit.config import getConfig

config = getConfig()


class UserSafe(config.get_model("user").User.get_pydantic(exclude={"password"})):
pass


class RoleSafe(config.get_model("role").BaseRole):
users: List[UserSafe]
8 changes: 6 additions & 2 deletions freenit/models/sql/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ async def patch(self, fields):
class OrmarUserMixin:
id: int = ormar.Integer(primary_key=True)
email: pydantic.EmailStr = ormar.Text(unique=True)
password: str = ormar.Text(nullable=True)
password: str = ormar.Text()
fullname: str = ormar.Text(nullable=True)
active: bool = ormar.Boolean(default=False)
admin: bool = ormar.Boolean(default=False)


class OrmarRoleMixin:
id: int = ormar.Integer(primary_key=True)
name: str = ormar.Text(unique=True)
name: str = ormar.Text(unique=True, index=True)


ormar_config = ormar.OrmarConfig(
Expand All @@ -44,3 +44,7 @@ class OrmarRoleMixin:
def make_optional(OptionalModel):
for field_name in OptionalModel.model_fields:
OptionalModel.model_fields[field_name].default = None


class BaseRole(OrmarBaseModel, OrmarRoleMixin):
ormar_config = ormar_config.copy()
7 changes: 3 additions & 4 deletions freenit/models/sql/role.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from .base import OrmarBaseModel, OrmarRoleMixin, make_optional, ormar_config
from .base import BaseRole, ormar_config, make_optional


class Role(OrmarBaseModel, OrmarRoleMixin):
class Role(BaseRole):
ormar_config = ormar_config.copy()


class RoleOptional(Role):
class RoleOptional(BaseRole):
pass


Expand Down
2 changes: 1 addition & 1 deletion freenit/models/sql/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from fastapi import HTTPException

from freenit.auth import verify
from freenit.models.sql.base import (
from .base import (
OrmarBaseModel,
OrmarUserMixin,
make_optional,
Expand Down
10 changes: 8 additions & 2 deletions freenit/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@

config = getConfig()
auth = config.get_model("user")
User = auth.User
UserOptional = auth.UserOptionalPydantic


class User(auth.User):
pass


class UserOptional(auth.UserOptional):
pass