Update/fix login

This commit is contained in:
phil 2024-03-16 11:18:33 +05:30
parent ba1f59cfb9
commit 15fe7fab08
4 changed files with 56 additions and 8 deletions

35
pdm.lock generated
View file

@ -5,7 +5,7 @@
groups = ["default", "dev", "mqtt"] groups = ["default", "dev", "mqtt"]
strategy = ["cross_platform"] strategy = ["cross_platform"]
lock_version = "4.4.1" lock_version = "4.4.1"
content_hash = "sha256:0d9a5dffa5c1766fc8e78cd0c4faffa2d4640e5bb98e7456413ce64d346e0b86" content_hash = "sha256:5ff6f2ee76615362a8ae23881594246320dde93e417b6abc972506f1bf27816b"
[[package]] [[package]]
name = "aiomqtt" name = "aiomqtt"
@ -1207,6 +1207,16 @@ files = [
{file = "traitlets-5.14.0.tar.gz", hash = "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772"}, {file = "traitlets-5.14.0.tar.gz", hash = "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772"},
] ]
[[package]]
name = "types-passlib"
version = "1.7.7.20240311"
requires_python = ">=3.8"
summary = "Typing stubs for passlib"
files = [
{file = "types-passlib-1.7.7.20240311.tar.gz", hash = "sha256:287dd27cec5421daf6be5c295f681baf343c146038c8bde4db783bcac1beccb7"},
{file = "types_passlib-1.7.7.20240311-py3-none-any.whl", hash = "sha256:cd44166e9347ae516f4830046cd1673c1ef90a5cc7ddd1356cf8a14892f29249"},
]
[[package]] [[package]]
name = "types-psycopg2" name = "types-psycopg2"
version = "2.9.21.20" version = "2.9.21.20"
@ -1217,6 +1227,29 @@ files = [
{file = "types_psycopg2-2.9.21.20-py3-none-any.whl", hash = "sha256:5b1e2e1d9478f8a298ea7038f8ea988e0ccc1f0af39f84636d57ef0da6f29e95"}, {file = "types_psycopg2-2.9.21.20-py3-none-any.whl", hash = "sha256:5b1e2e1d9478f8a298ea7038f8ea988e0ccc1f0af39f84636d57ef0da6f29e95"},
] ]
[[package]]
name = "types-pyasn1"
version = "0.5.0.20240301"
requires_python = ">=3.8"
summary = "Typing stubs for pyasn1"
files = [
{file = "types-pyasn1-0.5.0.20240301.tar.gz", hash = "sha256:da328f5771d54a2016863270b281047f9cc38e39f65a297ba9f987d5de3403f1"},
{file = "types_pyasn1-0.5.0.20240301-py3-none-any.whl", hash = "sha256:d9989899184bbd6e2adf6f812c8f49c48197fceea251a6fb13666dae3203f80d"},
]
[[package]]
name = "types-python-jose"
version = "3.3.4.20240106"
requires_python = ">=3.8"
summary = "Typing stubs for python-jose"
dependencies = [
"types-pyasn1",
]
files = [
{file = "types-python-jose-3.3.4.20240106.tar.gz", hash = "sha256:b18cf8c5080bbfe1ef7c3b707986435d9efca3e90889acb6a06f65e06bc3405a"},
{file = "types_python_jose-3.3.4.20240106-py3-none-any.whl", hash = "sha256:b515a6c0c61f5e2a53bc93e3a2b024cbd42563e2e19cbde9fd1c2cc2cfe77ccc"},
]
[[package]] [[package]]
name = "types-pytz" name = "types-pytz"
version = "2023.3.1.1" version = "2023.3.1.1"

View file

@ -54,4 +54,6 @@ dev = [
"types-psycopg2>=2.9.21.20", "types-psycopg2>=2.9.21.20",
"types-PyYAML>=6.0.12.12", "types-PyYAML>=6.0.12.12",
"asyncpg-stubs>=0.29.1", "asyncpg-stubs>=0.29.1",
"types-python-jose>=3.3.4.20240106",
"types-passlib>=1.7.7.20240311",
] ]

View file

@ -1,4 +1,6 @@
from sqlmodel import Field, SQLModel, Relationship from datetime import datetime
from sqlmodel import Field, SQLModel, Relationship, String
from pydantic import BaseModel from pydantic import BaseModel
from gisaf.models.metadata import gisaf_admin from gisaf.models.metadata import gisaf_admin
@ -27,10 +29,20 @@ class UserBase(SQLModel):
class User(UserBase, table=True): class User(UserBase, table=True):
__table_args__ = gisaf_admin.table_args __table_args__ = gisaf_admin.table_args
id: str | None = Field(default=None, primary_key=True)
id: int = Field(primary_key=True)
username: str = Field(String(255), unique=True, index=True)
email: str = Field(sa_type=String(50), unique=True)
password: str = Field(sa_type=String(255))
active: bool
confirmed_at: datetime
last_login_at: datetime
current_login_at: datetime
last_login_ip: str = Field(sa_type=String(255))
current_login_ip: str = Field(sa_type=String(255))
login_count: int
roles: list["Role"] = Relationship(back_populates="users", roles: list["Role"] = Relationship(back_populates="users",
link_model=UserRoleLink) link_model=UserRoleLink)
password: str | None = None
def can_view(self, model) -> bool: def can_view(self, model) -> bool:
role = getattr(model, 'viewable_role', None) role = getattr(model, 'viewable_role', None)

View file

@ -10,7 +10,7 @@ from pydantic import BaseModel
from sqlmodel.ext.asyncio.session import AsyncSession from sqlmodel.ext.asyncio.session import AsyncSession
from jose import JWTError, jwt, ExpiredSignatureError from jose import JWTError, jwt, ExpiredSignatureError
from sqlalchemy import select from sqlmodel import select
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from gisaf.config import conf from gisaf.config import conf
@ -72,7 +72,8 @@ async def enable_user(session: AsyncSession, username: str, enable=True):
await session.commit() await session.commit()
async def create_user(session: AsyncSession, username: str, password: str, full_name: str, async def create_user(session: AsyncSession, username: str,
password: str, full_name: str,
email: str, **kwargs): email: str, **kwargs):
user_in_db: User | None = await get_user(session, username) user_in_db: User | None = await get_user(session, username)
if user_in_db is None: if user_in_db is None:
@ -93,10 +94,10 @@ async def create_user(session: AsyncSession, username: str, password: str, full_
async def get_user( async def get_user(
session: AsyncSession, session: AsyncSession,
username: str) -> (User | None): username: str) -> User | None:
query = select(User).where(User.username==username).options(selectinload(User.roles)) query = select(User).where(User.username==username).options(selectinload(User.roles))
data = await session.exec(query) data = await session.exec(query)
return data.scalar() return data.one_or_none()
def verify_password(user: User, plain_password): def verify_password(user: User, plain_password):