wip
This commit is contained in:
parent
538e901fcb
commit
2bf6bc6e77
2 changed files with 88 additions and 18 deletions
|
|
@ -457,6 +457,48 @@ class Rating:
|
|||
ratings = Rating.__table__
|
||||
|
||||
|
||||
# TODO
|
||||
# - distinguish between ratings & watches
|
||||
# - they are completely separate
|
||||
# - I can rate something at any time, without having watched it, e.g. in a discussion with a friend I change my opinion on a movie
|
||||
# - I can watch something without having fully formed an opinion yet, i.e. I don't want to rate it yet
|
||||
|
||||
|
||||
@mapper_registry.mapped
|
||||
@dataclass
|
||||
class Watch:
|
||||
__table__: ClassVar[Table] = Table(
|
||||
"watches",
|
||||
metadata,
|
||||
Column("id", String, primary_key=True), # ULID
|
||||
Column("movie_id", ForeignKey("movies.id"), nullable=False), # ULID
|
||||
Column("user_id", ForeignKey("users.id"), nullable=False), # ULID
|
||||
Column("started", String, nullable=False), # datetime
|
||||
Column("finished", String), # datetime
|
||||
Column("geoloc", String), # geo coords
|
||||
Column("score", Integer), #
|
||||
Column("favorite", Integer), # bool
|
||||
)
|
||||
|
||||
id: ULID = field(default_factory=ULID)
|
||||
|
||||
movie_id: ULID = None
|
||||
movie: Relation[Movie] = None
|
||||
|
||||
user_id: ULID = None
|
||||
user: Relation[User] = None
|
||||
|
||||
started: datetime | None = None
|
||||
finished: datetime | None = None
|
||||
|
||||
geoloc: str | None = None
|
||||
score: int | None = None # range: [0,100]
|
||||
favorite: bool | None = None
|
||||
|
||||
|
||||
watches = Rating.__table__
|
||||
|
||||
|
||||
class GroupUser(TypedDict):
|
||||
id: str
|
||||
name: str
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ class BearerAuthBackend(AuthenticationBackend):
|
|||
self.admin_tokens = {v: k for k, v in credentials.items()}
|
||||
|
||||
async def authenticate(self, conn: HTTPConnection):
|
||||
if "Authorization" not in conn.headers:
|
||||
if "authorization" not in conn.headers:
|
||||
return
|
||||
|
||||
# XXX should we remove the auth header after reading, for security reasons?
|
||||
|
||||
auth = conn.headers["Authorization"]
|
||||
auth = conn.headers["authorization"]
|
||||
try:
|
||||
scheme, credentials = auth.split()
|
||||
except ValueError as err:
|
||||
|
|
@ -62,23 +62,24 @@ class BearerAuthBackend(AuthenticationBackend):
|
|||
|
||||
roles = []
|
||||
|
||||
if scheme.lower() == "bearer":
|
||||
is_admin = credentials in self.admin_tokens
|
||||
if not is_admin:
|
||||
match scheme.lower():
|
||||
case "bearer":
|
||||
is_admin = credentials in self.admin_tokens
|
||||
if not is_admin:
|
||||
return
|
||||
name = self.admin_tokens[credentials]
|
||||
user = SimpleUser(name)
|
||||
roles.append("admin")
|
||||
|
||||
case "basic":
|
||||
try:
|
||||
name, secret = b64decode(credentials).decode().split(":")
|
||||
except Exception as err:
|
||||
raise AuthenticationError("Invalid auth credentials") from err
|
||||
user = AuthedUser(name, secret)
|
||||
|
||||
case _:
|
||||
return
|
||||
name = self.admin_tokens[credentials]
|
||||
user = SimpleUser(name)
|
||||
roles.append("admin")
|
||||
|
||||
elif scheme.lower() == "basic":
|
||||
try:
|
||||
name, secret = b64decode(credentials).decode().split(":")
|
||||
except Exception as err:
|
||||
raise AuthenticationError("Invalid auth credentials") from err
|
||||
user = AuthedUser(name, secret)
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
return AuthCredentials(["authenticated", *roles]), user
|
||||
|
||||
|
|
@ -366,6 +367,33 @@ async def progress_for_load_imdb_movies(request):
|
|||
return JSONResponse(resp)
|
||||
|
||||
|
||||
@route("/users/{user_id}/watches", methods=["POST"])
|
||||
@requires(["authenticated"])
|
||||
async def users_watching_start(request):
|
||||
# {
|
||||
# id
|
||||
# movie_id
|
||||
# location (gps)
|
||||
# started
|
||||
# finished
|
||||
# score
|
||||
# fav
|
||||
# }
|
||||
pass
|
||||
|
||||
|
||||
@route("/users/{user_id}/watches/{id}", methods=["PUT"])
|
||||
@requires(["authenticated"])
|
||||
async def users_watching_done(request):
|
||||
# {
|
||||
# ...
|
||||
# finished
|
||||
# score
|
||||
# fav
|
||||
# }
|
||||
pass
|
||||
|
||||
|
||||
_import_lock = asyncio.Lock()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue