core.modules.user¶
Classes¶
Status enum for a user |
|
This is a container-object holding information about one database entity. |
|
This is the root module prototype that serves a minimal module in the ViUR system without any other bindings. |
|
Abstract class for all primary authentication methods. |
|
Abstract class for all primary authentication methods. |
|
Abstract class for all primary authentication methods. |
|
Abstract class for all second factors. |
|
Abstract class for all second factors. |
|
This class handles the second factor for apps like authy and so on |
|
The User module is used to manage and authenticate users in a ViUR system. |
Functions¶
Create a new Admin user, if the userDB is empty |
|
|
Module Contents¶
- class core.modules.user.Status(*args, **kwds)¶
Bases:
enum.EnumStatus enum for a user
Has backwards compatibility to be comparable with non-enum values. Will be removed with viur-core 4.0.0
- UNSET = 0¶
- WAITING_FOR_EMAIL_VERIFICATION = 1¶
- WAITING_FOR_ADMIN_VERIFICATION = 2¶
- DISABLED = 5¶
- ACTIVE = 10¶
- __eq__(other)¶
- __lt__(other)¶
- class core.modules.user.UserSkel(*args, **kwargs)¶
Bases:
viur.core.skeleton.SkeletonThis is a container-object holding information about one database entity.
It has to be sub-classed with individual information about the kindName of the entities and its specific data attributes, the so called bones. The Skeleton stores its bones in an
OrderedDict-Instance, so the definition order of the contained bones remains constant.- Variables:
key (server.bones.BaseBone) – This bone stores the current database key of this entity. Assigning to this bones value is dangerous and does not affect the actual key its stored in.
creationdate (server.bones.DateBone) – The date and time where this entity has been created.
changedate (server.bones.DateBone) – The date and time of the last change to this entity.
Constructor for the UserSkel-class, with the capability to dynamically add bones required for the configured authentication methods.
- kindName = 'user'¶
Specifies the entity kind name this Skeleton is associated with. Will be determined automatically when not explicitly set.
- name¶
- firstname¶
- lastname¶
- roles¶
- access¶
- status¶
- lastlogin¶
- admin_config¶
- classmethod write(skel, *args, **kwargs)¶
Write current Skeleton to the datastore.
Stores the current data of this instance into the database. If an key value is set to the object, this entity will ne updated; Otherwise a new entity will be created.
To read a Skeleton object from the data store, see
read().- Parameters:
key – Allows to specify a key that is set to the skeleton and used for writing.
update_relations – If False, this entity won’t be marked dirty; This avoids from being fetched by the background task updating relations.
- Returns:
The Skeleton.
- class core.modules.user.UserAuthentication(moduleName, modulePath, userModule)¶
Bases:
viur.core.Module,abc.ABCThis is the root module prototype that serves a minimal module in the ViUR system without any other bindings.
- property METHOD_NAME: str¶
Define a unique method name for this authentication.
- Return type:
str
- property NAME: str¶
Define a descriptive name for this authentication.
- Return type:
str
- property VISIBLE: bool¶
Defines if the authentication method is visible to the user.
- Return type:
bool
- _user_module¶
- start_url = 'Uninferable/login'¶
- can_handle(skel)¶
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- Return type:
bool
- classmethod patch_user_skel(skel_cls)¶
Allows for an UserAuthentication to patch the UserSkel class with additional bones which are required for the implemented authentication method.
- Parameters:
skel_cls (viur.core.skeleton.Skeleton)
- class core.modules.user.UserPrimaryAuthentication(moduleName, modulePath, userModule)¶
Bases:
UserAuthentication,abc.ABCAbstract class for all primary authentication methods.
- registrationEnabled = False¶
- abstractmethod login(*args, **kwargs)¶
- next_or_finish(skel)¶
Hook that is called whenever a part of the authentication was successful. It allows to perform further steps in custom authentications, e.g. change a password after first login.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- class core.modules.user.UserPassword(moduleName, modulePath, userModule)¶
Bases:
UserPrimaryAuthenticationAbstract class for all primary authentication methods.
- METHOD_NAME = 'X-VIUR-AUTH-User-Password'¶
Define a unique method name for this authentication.
- NAME = 'Username & Password'¶
Define a descriptive name for this authentication.
- registrationEmailVerificationRequired = True¶
- registrationAdminVerificationRequired = True¶
- verifySuccessTemplate = 'user_verify_success'¶
- verifyEmailAddressMail = 'user_verify_address'¶
- verifyFailedTemplate = 'user_verify_failed'¶
- passwordRecoveryMail = 'user_password_recovery'¶
- passwordRecoverySuccessTemplate = 'user_passwordrecover_success'¶
- passwordRecoveryTemplate = 'user_passwordrecover'¶
- passwordRecoveryRateLimit¶
- loginRateLimit¶
- classmethod patch_user_skel(skel_cls)¶
Modifies the UserSkel to be equipped by a PasswordBone.
- class LoginSkel¶
Bases:
viur.core.skeleton.RelSkelThis is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for
RelationalBone.It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.
The Skeleton stores its bones in an
OrderedDict-Instance, so the definition order of the contained bones remains constant.- name¶
- password¶
- class LostPasswordStep1Skel¶
Bases:
viur.core.skeleton.RelSkelThis is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for
RelationalBone.It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.
The Skeleton stores its bones in an
OrderedDict-Instance, so the definition order of the contained bones remains constant.- name¶
- class LostPasswordStep2Skel¶
Bases:
viur.core.skeleton.RelSkelThis is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for
RelationalBone.It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.
The Skeleton stores its bones in an
OrderedDict-Instance, so the definition order of the contained bones remains constant.- recovery_key¶
- class LostPasswordStep3Skel¶
Bases:
viur.core.skeleton.RelSkelThis is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for
RelationalBone.It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.
The Skeleton stores its bones in an
OrderedDict-Instance, so the definition order of the contained bones remains constant.- recovery_key¶
- password¶
- login(**kwargs)¶
- pwrecover(recovery_key=None, skey=None, **kwargs)¶
This implements a password recovery process which lets users set a new password for their account, after validating a recovery key sent by email.
The process is as following:
The user enters the registered email adress (not validated here)
A random code is generated and stored as a security-ke, then sendUserPasswordRecoveryCode is called.
sendUserPasswordRecoveryCode will run in the background, check if we have a user with that name and send a link with the code. It runs as a deferred task so no information if a user account exists is being leaked.
If the user received an email, the link can be clicked to set a new password for the account.
To prevent automated attacks, the first step is guarded by limited calls to this function to 10 actions per 15 minutes. (One complete recovery process consists of two calls).
- Parameters:
recovery_key (str | None)
skey (str | None)
- sendUserPasswordRecoveryCode(user_name, recovery_key, user_agent)¶
Sends the given recovery code to the user given in userName. This function runs deferred so there’s no timing sidechannel that leaks if this user exists. Per default, we’ll send the code by email (assuming we have working email delivery), but this can be overridden to send it by SMS or other means. We’ll also update the changedate for this user, so no more than one code can be send to any given user in four hours.
- Parameters:
user_name (str)
recovery_key (str)
user_agent (str)
- Return type:
None
- verify(data)¶
- canAdd()¶
- Return type:
bool
- addSkel()¶
Prepare the add-Skel for rendering. Currently only calls self._user_module.addSkel() and sets skel[“status”] depending on self.registrationEmailVerificationRequired and self.registrationAdminVerificationRequired :return: viur.core.skeleton.Skeleton
- add(*, bounce=False, **kwargs)¶
Allows guests to register a new account if self.registrationEnabled is set to true
- Returns:
The rendered, added object of the entry, eventually with error hints.
- Raises:
viur.core.errors.Unauthorized, if the current user does not have the required permissions.- Raises:
viur.core.errors.PreconditionFailed, if the skey could not be verified.- Parameters:
bounce (bool)
- class core.modules.user.GoogleAccount(moduleName, modulePath, userModule)¶
Bases:
UserPrimaryAuthenticationAbstract class for all primary authentication methods.
- METHOD_NAME = 'X-VIUR-AUTH-Google-Account'¶
Define a unique method name for this authentication.
- NAME = 'Google Account'¶
Define a descriptive name for this authentication.
- classmethod patch_user_skel(skel_cls)¶
Modifies the UserSkel to be equipped by a bones required by Google Auth
- login(token=None, *args, **kwargs)¶
- Parameters:
token (str | None)
- class core.modules.user.UserSecondFactorAuthentication(moduleName, modulePath, _user_module)¶
Bases:
UserAuthentication,abc.ABCAbstract class for all second factors.
- MAX_RETRY = 3¶
- second_factor_login_template = 'user_login_secondfactor'¶
Template to enter the TOPT on login
- property NAME: str¶
- Abstractmethod:
- Return type:
str
Name for this factor for templates.
- property ACTION_NAME: str¶
- Abstractmethod:
- Return type:
str
The action name for this factor, used as path-segment.
- action_url = 'Uninferable/Uninferable'¶
- add_url = 'Uninferable/add'¶
- start_url = 'Uninferable/start'¶
- class core.modules.user.TimeBasedOTP(moduleName, modulePath, _user_module)¶
Bases:
UserSecondFactorAuthenticationAbstract class for all second factors.
- METHOD_NAME = 'X-VIUR-2FACTOR-TimeBasedOTP'¶
Define a unique method name for this authentication.
- WINDOW_SIZE = 5¶
- ACTION_NAME = 'otp'¶
The action name for this factor, used as path-segment.
- NAME = 'Time-based OTP'¶
Name for this factor for templates.
- second_factor_login_template = 'user_login_secondfactor'¶
Template to enter the TOPT on login
- class OtpConfig¶
This dataclass is used to provide an interface for a OTP token algorithm description that is passed within the TimeBasedOTP class for configuration.
- secret: str¶
- timedrift: float = 0.0¶
- algorithm: viur.core.decorators.t.Literal[sha1, sha256] = 'sha1'¶
- interval: int = 60¶
- class OtpSkel¶
Bases:
viur.core.skeleton.RelSkelThis is the Skeleton used to ask for the OTP token.
- otptoken¶
- classmethod patch_user_skel(skel_cls)¶
Modifies the UserSkel to be equipped by a bones required by Timebased OTP
- get_config(skel)¶
Returns an instance of self.OtpConfig with a provided token configuration, or None when there is no appropriate configuration of this second factor handler available.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- Return type:
OtpConfig | None
- can_handle(skel)¶
Specified whether the second factor authentication can be handled by the given user or not.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- Return type:
bool
- start()¶
Configures OTP login for the current session.
A special otp_user_conf has to be specified as a dict, which is stored into the session.
- otp(*args, **kwargs)¶
Performs the second factor validation and interaction with the client.
- static verify(otp, secret, algorithm='sha1', interval=60, timedrift=0.0, for_time=None, valid_window=0)¶
Verifies the OTP passed in against the current time OTP.
This is a fork of pyotp.verify. Rather than true/false, if valid_window > 0, it returns the index for which the OTP value obtained by pyotp.at(for_time=time.time(), counter_offset=index) equals the current value shown on the hardware token generator. This can be used to store the time drift of a given token generator.
- Parameters:
otp (str | int) – the OTP token to check against
secret (str) – The OTP secret
algorithm (str) – digest function to use in the HMAC (expected to be sha1 or sha256)
interval (int) – the time interval in seconds for OTP. This defaults to 60 (old OTP c200 Generators).
timedrift (float) – The known timedrift (old index) of the hardware OTP generator
for_time (datetime.datetime | None) – Time to check OTP at (defaults to now)
valid_window (int) – extends the validity to this many counter ticks before and after the current one
- Returns:
The index where verification succeeded, None otherwise
- Return type:
int | None
- updateTimeDrift(user_key, idx)¶
Updates the clock-drift value.
The value is only changed in 1/10 steps, so that a late submit by an user doesn’t skew it out of bounds. Maximum change per call is 0.3 minutes.
- Parameters:
user_key (viur.core.db.Key) – For which user should the update occour
idx (float) – How many steps before/behind was that token
- Return type:
None
- class core.modules.user.AuthenticatorOTP(moduleName, modulePath, _user_module)¶
Bases:
UserSecondFactorAuthenticationThis class handles the second factor for apps like authy and so on
- METHOD_NAME = 'X-VIUR-2FACTOR-AuthenticatorOTP'¶
Define a unique method name for this authentication.
- ACTION_NAME = 'authenticator_otp'¶
Action name provided for otp_template on login
- NAME = 'Authenticator App'¶
@exposed @force_ssl @skey(allow_empty=True) def add(self, otp=None):
“”” We try to read the otp_app_secret from the current session. When this fails we generate a new one and store it in the session.
If an otp and a skey are provided we are validate the skey and the otp. If both is successfully we store the otp_app_secret from the session in the user entry. “”” current_session = current.session.get()
- if not (otp_app_secret := current_session.get(“_maybe_otp_app_secret”)):
otp_app_secret = AuthenticatorOTP.generate_otp_app_secret() current_session[“_maybe_otp_app_secret”] = otp_app_secret current_session.markChanged()
- if otp is None:
- return self._user_module.render.second_factor_add(
tpl=self.second_factor_add_template, action_name=self.ACTION_NAME, name=i18n.translate(
f”viur.core.modules.user.auth{self.ACTION_NAME}”, default_variables={“name”: self.NAME},
), add_url=self.add_url, otp_uri=AuthenticatorOTP.generate_otp_app_secret_uri(otp_app_secret))
- else:
- if not AuthenticatorOTP.verify_otp(otp, otp_app_secret):
- return self._user_module.render.second_factor_add(
tpl=self.second_factor_add_template, action_name=self.ACTION_NAME, name=i18n.translate(
f”viur.core.modules.user.auth.{self.ACTION_NAME}”, default_variables={“name”: self.NAME},
), add_url=self.add_url, otp_uri=AuthenticatorOTP.generate_otp_app_secret_uri(otp_app_secret)) # to add errors
# Now we can set the otp_app_secret to the current User and render der Success-template AuthenticatorOTP.set_otp_app_secret(otp_app_secret) return self._user_module.render.second_factor_add_success(
action_name=self.ACTION_NAME, name=i18n.translate(
f”viur.core.modules.user.auth.{self.ACTION_NAME}”, default_variables={“name”: self.NAME},
),
)
- can_handle(skel)¶
We can only handle the second factor if we have stored an otp_app_secret before.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- Return type:
bool
- classmethod patch_user_skel(skel_cls)¶
Modifies the UserSkel to be equipped by bones required by Authenticator App
- classmethod set_otp_app_secret(otp_app_secret=None)¶
Write a new OTP Token in the current user entry.
- classmethod generate_otp_app_secret_uri(otp_app_secret)¶
:return an otp uri like otpauth://totp/Example:alice@google.com?secret=ABCDEFGH1234&issuer=Example
- Return type:
str
- classmethod generate_otp_app_secret()¶
Generate a new OTP Secret :return an otp
- Return type:
str
- classmethod verify_otp(otp, secret)¶
- Parameters:
otp (str | int)
secret (str)
- Return type:
bool
- start()¶
- authenticator_otp(**kwargs)¶
We verify the otp here with the secret we stored before.
- class core.modules.user.User(moduleName, modulePath)¶
Bases:
viur.core.prototypes.list.ListThe User module is used to manage and authenticate users in a ViUR system.
It is used in almost any ViUR project, but ViUR can also function without any user capabilites.
- kindName = 'user'¶
Name of the datastore kind that is handled by this module.
This information is used to bind a specific
viur.core.skeleton.Skeleton-class to this prototype. By default, it is automatically determined from the module’s class name, so a module named Animal refers to a Skeleton named AnimalSkel and its kindName is animal.For more information, refer to the function
_resolveSkelCls().
- addTemplate = 'user_add'¶
- addSuccessTemplate = 'user_add_success'¶
- authenticationProviders: viur.core.decorators.t.Iterable[UserPrimaryAuthentication]¶
Specifies primary authentication providers that are made available as sub-modules under user/auth_<classname>. They might require customization or configuration.
- secondFactorProviders: viur.core.decorators.t.Iterable[UserSecondFactorAuthentication]¶
Specifies secondary authentication providers that are made available as sub-modules under user/f2_<classname>. They might require customization or configuration, which is determined during the login-process depending on the user that wants to login.
- validAuthenticationMethods¶
Specifies the possible combinations of primary- and secondary factor login methos.
GoogleLogin defaults to no second factor, as the Google Account can be secured by a secondary factor. AuthenticatorOTP and TimeBasedOTP are only handled when there is a user-dependent configuration available.
- msg_missing_second_factor = 'Second factor required but not configured for this user.'¶
- secondFactorTimeWindow¶
- default_order = 'name.idx'¶
Allows to specify a default order for this module, which is applied when no other order is specified.
Setting a default_order might result in the requirement of additional indexes, which are being raised and must be specified.
- roles¶
Allows to specify role settings for a module.
Defaults to no role definition, which ignores the module entirely in the role-system. In this case, access rights can still be set individually on the user’s access bone.
A “*” wildcard can either be used as key or as value to allow for “all roles”, or “all rights”.
# Example roles = { "*": "view", # Any role may only "view" "editor": ("add", "edit"), # Role "editor" may "add" or "edit", but not "delete" "admin": "*", # Role "admin" can do everything }
- adminInfo()¶
This is a
dictholding the information necessary for the Vi/Admin to handle this module.- name:
str Human-readable module name that will be shown in the admin tool.
- handler:
str(list,treeorsingleton): Allows to override the handler provided by the module. Set this only when really necessary, otherwise it can be left out and is automatically injected by the Module’s prototype.
- icon:
str (Optional) Either the Shoelace icon library name or a path relative to the project’s deploy folder (e.g. /static/icons/viur.svg) for the icon used in the admin tool for this module.
- columns:
List[str] (Optional) List of columns (bone names) that are displayed by default. Used only by the List handler.
- filter:
Dict[str, str] (Optional) Dictionary of additional parameters that will be send along when fetching entities from the server. Can be used to filter the entities being displayed on the client-side.
- display:
str(“default”, “hidden” or “group”) (Optional) “hidden” will hide the module in the admin tool’s main bar. (itwill not be accessible directly, however it’s registered with the frontend so it can be used in a relational bone). “group” will show this module in the main bar, but it will not be clickable. Clicking it will just try to expand it (assuming there are additional views defined).
- preview:
Union[str, Dict[str, str]] (Optional) A url that will be opened in a new tab and is expected to display the entity selected in the table. Can be “/{{module}}/view/{{key}}”, with {{module}} and {{key}} getting replaced as needed. If more than one preview-url is needed, supply a dictionary where the key is the URL and the value the description shown to the user.
- views:
List[Dict[str, t.Any]] (Optional) List of nested adminInfo like dictionaries. Used to define additional views on the module. Useful f.e. for an order module, where you want separate list of “payed orders”, “unpayed orders”, “orders waiting for shipment”, etc. If such views are defined, the top-level entry in the menu bar will expand if clicked, revealing these additional filters.
- actions:
List[str] (Optional) List of actions supported by this modules. Actions can be defined by the frontend (like “add”, “edit”, “delete” or “preview”); it can be an action defined by a plugin loaded by the frontend; or it can be a so called “server side action” (see “customActions” below)
- customActions:
Dict[str, dict] (Optional) A mapping of names of server-defined actions that can be used in the
actionslist above to their definition dictionary. See …. for more details.- disabledActions:
List[str, dict] (Optional) A list of disabled actions. The frontend will inject default actions like add or edit even if they’re not listed in actions. Listing them here will prevent that. It’s up to the frontend to decide if that action won’t be visible at all or it’s button just being disabled.
- sortIndex:
int (Optional) Defines the order in which the modules will appear in the main bar in ascrending order.
- indexedBones:
List[str] (Optional) List of bones, for which an (composite?) index exists in this view. This allows the fronted to signal the user that a given list can be sorted or filtered by this bone. If no additional filters are enforced by the
listFilterandfilteris not set, this should be all bones which are marked as indexed.- changeInvalidates:
List[str] (Optional) A list of module-names which depend on the entities handled from this module. This allows the frontend to invalidate any caches in these depended modules if the data in this module changes. Example: This module may be a list-module handling the file_rootNode entities for the file module, so a edit/add/deletion action on this module should be reflected in the rootNode-selector in the file-module itself. In this case, this property should be set to
["file"].- moduleGroup:
str (Optional) If set, should be a key of a moduleGroup defined in …. .
- editViews:
Dict[str, t.Any] (Optional) If set, will embed another list-widget in the edit forms for a given entity. See …. for more details.
If this is a function, it must take no parameters and return the dictionary as shown above. This can be used to customize the appearance of the Vi/Admin to individual users.
- name:
- get_role_defaults(role)¶
Returns a set of default access rights for a given role.
Defaults to “admin” usage for any role > “user” and “scriptor” usage for “admin” role.
- Parameters:
role (str)
- Return type:
set[str]
- addSkel()¶
Retrieve a new instance of a
viur.core.skeleton.Skeletonthat is used by the application for adding an entry to the list.The default is a Skeleton instance returned by
baseSkel().Like in
viewSkel(), the skeleton can be post-processed. Bones that are being removed aren’t visible and cannot be set, but it’s also possible to just set a bone to readOnly (revealing it’s value to the user, but preventing any modification. It’s possible to pre-set values on that skeleton (and if that bone is readOnly, enforcing these values).See also
viewSkel(),editSkel(),baseSkel()- Returns:
Returns a Skeleton instance for adding an entry.
- editSkel(*args, **kwargs)¶
Retrieve a new instance of a
viur.core.skeleton.Skeletonthat is used by the application for editing an existing entry from the list.The default is a Skeleton instance returned by
baseSkel().Like in
viewSkel(), the skeleton can be post-processed. Bones that are being removed aren’t visible and cannot be set, but it’s also possible to just set a bone to readOnly (revealing it’s value to the user, but preventing any modification.See also
viewSkel(),editSkel(),baseSkel()- Returns:
Returns a Skeleton instance for editing an entry.
- secondFactorProviderByClass(cls)¶
- Return type:
- getCurrentUser()¶
- continueAuthenticationFlow(provider, user_key)¶
Continue authentication flow when primary authentication succeeded.
- Parameters:
provider (UserPrimaryAuthentication)
user_key (viur.core.db.Key)
- secondFactorSucceeded(provider, user_key)¶
Continue authentication flow when secondary authentication succeeded.
- Parameters:
provider (UserSecondFactorAuthentication)
user_key (viur.core.db.Key)
- is_active(skel)¶
Hookable check if a user is defined as “active” and can login.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance) – The UserSkel of the user who wants to login.
- Returns:
Returns True or False when the result is unambigous and the user is active or not. Returns None when the provided skel doesn’t provide enough information for determination.
- Return type:
bool | None
- is_admin(skel)¶
Hookable check if a user is defined as “admin” and can edit or log into other users. Defaults to “root” users only.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance) – The UserSkel of the user who wants should be checked for user admin privileges.
- Returns:
Returns True or False when the result is unambigous and the user is admin or not. Returns None when the provided skel doesn’t provide enough information for determination.
- Return type:
bool | None
- authenticateUser(key, **kwargs)¶
Performs Log-In for the current session and the given user key.
This resets the current session: All fields not explicitly marked as persistent by conf.user.session_persistent_fields_on_login are gone afterwards.
- Parameters:
key (viur.core.db.Key) – The (DB-)Key of the user we shall authenticate
- SelectAuthenticationProviderSkel()¶
- select_authentication_provider(**kwargs)¶
- class SelectSecondFactorProviderSkel¶
Bases:
viur.core.skeleton.RelSkelThis is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for
RelationalBone.It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.
The Skeleton stores its bones in an
OrderedDict-Instance, so the definition order of the contained bones remains constant.- provider¶
- select_secondfactor_provider(**kwargs)¶
- logout(**kwargs)¶
Implements the logout action. It also terminates the current session (all keys not listed in viur.session_persistent_fields_on_logout will be lost).
- login(*args, **kwargs)¶
- onLogin(skel)¶
Hook to be called on user login.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- onLogout(skel)¶
Hook to be called on user logout.
- Parameters:
skel (viur.core.skeleton.SkeletonInstance)
- view(key='self', *args, **kwargs)¶
Allow a special key “self” to reference the current user.
By default, any authenticated user can view its own user entry, to obtain access rights and any specific user information. This behavior is defined in the customized canView function, which is overwritten by the User-module.
The rendered skeleton can be modified or restriced by specifying a customized view-skeleton.
- Parameters:
key (viur.core.db.Key | int | str)
- canView(skel)¶
Checks if the current user can view the given entry. Should be identical to what’s allowed by listFilter. By default, meth:listFilter is used to determine what’s allowed and whats not; but this method can be overridden for performance improvements (to eliminate that additional database access). :param skel: The entry we check for :return: True if the current session is authorized to view that entry, False otherwise
- Return type:
bool
- edit(key='self', *args, **kwargs)¶
Allow a special key “self” to reference the current user.
This modification will only allow to use “self” as a key; The specific access right to let the user edit itself must still be customized.
The rendered and editable skeleton can be modified or restriced by specifying a customized edit-skeleton.
- Parameters:
key (viur.core.db.Key | int | str)
- getAuthMethods(*args, **kwargs)¶
Legacy method prior < viur-core 3.8: Inform tools like Admin which authentication to use
- trigger(action, key)¶
- Parameters:
action (str)
key (str)
- get_cookie_for_app(redirect_to=None)¶
Generates a session cookie for the currently logged-in user and hands it to an external client (script, native app, or WebView).
This endpoint is the entry point of a App Login Flow. A privileged user (admin/root) authenticates normally in the browser and then opens this URL. The backend creates a fresh ViUR session (see
_get_cookie_for_app()) and delivers the resultingSet-Cookiestring to the caller.Typical usage — local Python client / script:
The caller spins up a temporary local HTTP server (e.g. on
http://localhost:60000) and passes its address as redirect_to:/vi/user/get_cookie_for_app?redirect_to=http://localhost:60000
After the user authenticates in the browser, the backend redirects to:
http://localhost:60000?cookie=<url-encoded Set-Cookie string>&app=<project_id>
The local server can then extract only the
name=valuepart of the cookie string (everything before the first;) and use it for subsequent API calls:cookie_str = qs["cookie"][0] # full Set-Cookie value key, value = cookie_str.split(";", 1)[0].split("=") session.cookies.update({key: value})
The
appquery parameter is set by the server toconf.instance.project_idand lets the client distinguish between multiple backends / cache credentials per project.Alternative — WebView / browser redirect:
When the receiving side is a browser or WebView the full
Set-Cookiestring can be forwarded toapply_login_cookie()to let the framework activate the session.- Parameters:
redirect_to (str) –
Optional callback URL. When provided the caller is redirected to that URL with two query parameters appended automatically:
cookie– URL-encodedSet-Cookiestring (name=value;flags…).app– the server’s GCP project ID (conf.instance.project_id).
A
?is appended if the URL does not already contain one. When omitted, the rawSet-Cookiestring is returned astext/plain(useful for debugging or direct API calls).
Warning
Open-redirect / session-hijacking risk
Because the session cookie is appended as a plain query parameter, an attacker who can convince an authenticated admin to click a crafted link (e.g. via phishing) could redirect the browser to an evil server that simply harvests the
cookieparameter and gains full session access.To mitigate this, all
redirect_tovalues are validated againstconf.user.redirect_whitelistusingfnmatch.fnmatch(). Only explicitly whitelisted URL patterns are accepted; anything else is rejected with403 Forbidden. Configure the whitelist in your project to include every legitimate callback origin (local scripts, internal tooling, etc.).- Raises:
errors.Forbidden – When redirect_to does not match any pattern in
conf.user.redirect_whitelist.errors.Redirect – Always raised when redirect_to is supplied and allowed.
- Parameters:
redirect_to (str)
- _get_cookie_for_app()¶
Creates a new, standalone ViUR session for the current user and returns the corresponding
Set-Cookieheader value.Unlike the regular session created during a normal login, this session is intentionally not attached to the current HTTP request. Instead it is persisted directly in Datastore so that a different HTTP client can pick it up via
apply_login_cookie().The created session entity mirrors the structure of a regular
Sessionentry:data["user"]– the full userdbEntity(needed by the session loader).data["is_app_session"]– flag to distinguish app sessions from regular browser sessions.static_security_key– random value, same role as in normal sessions.lastseen– current timestamp so the session is not immediately garbage- collected.user– stringified user key for server-side user-based queries.
- Returns:
A
Set-Cookieheader value in the form<cookie_name>=<key>;<flags>where<flags>is produced bySession.build_flags()(Path=/; HttpOnly; SameSite=…; Secure; Max-Age=…).- Return type:
str
- apply_login_cookie(cookie)¶
Redirect endpoint to load session from the given cookie.
This is the second half of the App Login Flow. A native app or WebView that received a
Set-Cookiestring fromget_cookie_for_app()(typically via a redirect URL parameter) calls this endpoint to activate the embedded session for its own HTTP context.The flow is:
Parse the raw
Set-Cookiestring withhttp.cookies.SimpleCookie.Look for the expected session cookie name (
Session.cookie_name).Reset the caller’s current (anonymous) session.
Inject the cookie value into the current request’s cookie jar so that
Session.load()can find the pre-built Datastore session.Redirect to
/– from this point on the caller is fully authenticated.
- Parameters:
cookie (str) – A raw
Set-Cookieheader value as produced by_get_cookie_for_app(), e.g.viur_cookie_myproject=<key>;Path=/;HttpOnly;….- Raises:
errors.Redirect – On success – redirects to
/.errors.BadRequest – When the cookie string does not contain a recognisable session cookie (i.e.
Session.cookie_nameis absent after parsing).
- onEdited(skel)¶
Hook function that is called after modifying an entry.
It should be overridden for a module-specific behavior. The default is writing a log entry.
- Parameters:
skel – The Skeleton that has been modified.
See also
edit(),onEdit()
- onDeleted(skel)¶
Hook function that is called after deleting an entry.
It should be overridden for a module-specific behavior. The default is writing a log entry.
- Parameters:
skel – The Skeleton that has been deleted.
See also
delete(),onDelete()
- core.modules.user.createNewUserIfNotExists()¶
Create a new Admin user, if the userDB is empty
- core.modules.user.__getattr__(attr)¶