Skip to content

Commit

Permalink
[SDESK-7464] - Create new async Users Resource and Service (#2799)
Browse files Browse the repository at this point in the history
* Create new resource model for users resource

* Create new async resource service for user and dbuser

* Create resource config, users module and add it to MODULES config

* Suggested fixes

* Refactor previous types file into new dir

* Refactored id variable

* Removed __is_invalid_operation in resource
  • Loading branch information
BrianMwangi21 authored Jan 9, 2025
1 parent ae02d60 commit cd15fe5
Show file tree
Hide file tree
Showing 6 changed files with 608 additions and 1 deletion.
2 changes: 1 addition & 1 deletion superdesk/default_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ def local_to_utc_hour(hour):
#:
#: ..versionadded: 3.0.0
#:
MODULES = []
MODULES = ["superdesk.users"]

ASYNC_AUTH_CLASS = "superdesk.core.auth.token_auth:TokenAuthorization"

Expand Down
3 changes: 3 additions & 0 deletions superdesk/types.py → superdesk/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from typing import TypedDict, Dict, Any, List
from .users import UsersResourceModel

__all__ = ["UsersResourceModel"]


class WebsocketMessageFilterConditions(TypedDict, total=False):
Expand Down
79 changes: 79 additions & 0 deletions superdesk/types/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# -*- coding: utf-8; -*-
#
# This file is part of Superdesk.
#
# Copyright 2013, 2014 Sourcefabric z.u. and contributors.
#
# For the full copyright and license information, please see the
# AUTHORS and LICENSE files distributed with this source code, or
# at https://www.sourcefabric.org/superdesk/license

"""Superdesk Users"""


from datetime import datetime
from enum import Enum, unique
from typing import Annotated, Any

from pydantic import Field
from superdesk.core.resources import ResourceModel, fields
from superdesk.core.resources.fields import ObjectId
from superdesk.core.resources.validators import validate_unique_value_async, validate_data_relation_async


@unique
class UserTypeEnum(str, Enum):
USER = "user"
ADMINISTRATOR = "administrator"
EXTERNAL = "external"


class UsersResourceModel(ResourceModel):
username: Annotated[fields.Keyword, validate_unique_value_async("users", "username")]
password: str = Field(min_length=5)
password_changed_on: datetime | None = None
first_name: str
last_name: str
display_name: str
email: Annotated[fields.Keyword, validate_unique_value_async("users", "email")]
phone: str | None = None
job_title: str | None = None
biography: str | None = None
facebook: str | None = None
instagram: str | None = None
twitter: str | None = None
jid: Annotated[fields.Keyword, validate_unique_value_async("users", "jid")] | None = None
language: str | None = None
user_info: dict[str, Any] = Field(default_factory=dict)
picture_url: str | None = None
avatar: Annotated[ObjectId, validate_data_relation_async("upload")] | None = None
avatar_renditions: dict[str, Any] | None = Field(default=None)
role: Annotated[ObjectId, validate_data_relation_async("roles")]
privileges: dict[str, Any] = Field(default_factory=dict)
workspace: dict[str, Any] = Field(default_factory=dict)
user_type: UserTypeEnum = Field(default=UserTypeEnum.USER)
is_support: bool = Field(default=False)
is_author: bool = Field(default=True)
private: bool | None = Field(default=False)
is_active: bool = Field(default=True)
is_enabled: bool = Field(default=True)
needs_activation: bool = Field(default=True)
# Default desk of the user, selected when logged-in.
desk: Annotated[ObjectId, validate_data_relation_async("desks")] | None = None
# Used for putting a sign-off on the content when it's created/updated except kill
sign_off: str | None = None
byline: str | None = None
# List to hold invisible stages.
# This field is updated under the following scenarios:
# 1. Stage visible flag is updated
# 2. Desk membership is modified
# 3. New user is created
invisible_stages: list | None = Field(default=None)
# If Slack notifications are configured and enabled for the user
# the Slack username is stored here.
slack_username: str | None = None
# The Slack user id is stored here to avoid repeat look ups
slack_user_id: str | None = None
session_preferences: dict[str, Any] = Field(default_factory=dict)
user_preferences: dict[str, Any] = Field(default_factory=dict)
last_activity_at: datetime | None = None
5 changes: 5 additions & 0 deletions superdesk/users/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
from quart_babel import lazy_gettext
import superdesk
from apps import auth
from superdesk.core.module import Module

from .users import UsersResource
from .services import UsersService, DBUsersService, is_admin # noqa
from .module import users_resource_config


def init_app(app) -> None:
Expand Down Expand Up @@ -43,3 +45,6 @@ def get_user_from_request(required=False):
"""

return auth.get_user(required)


module = Module(name="superdesk.users", resources=[users_resource_config])
Loading

0 comments on commit cd15fe5

Please sign in to comment.