m_identity (zotonic_core v1.0.0-rc.17)
The m_identity model manages usernames and other user identities. mod_authentication uses it to store and check salted passwords, but also provides a safe storage for user tokens of any kind, as used by mod_facebook.
Note that a user does not have to be of the person category per se, in Zotonic anything can have identities attached to it.
The following m_identity model properties are available in templates:
| Property | Description | Example value |
|---|---|---|
| is_user | Check if a page id is a user. Return a bool. Usage: m.identity[page_id].is_user | true |
| username | Fetch the username, if any, of a user. Returns a binary or undefined. Usage: m.identity[page_id].username | <<"admin">> |
Available Model API Paths
| Method | Path pattern | Description |
|---|---|---|
get | /lookup/+type/+key/... | Return all filtered identity records matching normalized identity key +key for identity type +type (propb and secret fields are stripped; admin only). |
get | /generate_password/... | Return a newly generated random password string (z_ids:password/0). |
get | /is_email_verified | Return whether the current user’s primary email_raw has a matching verified email identity record. No further lookups. |
get | /is_email_verified/+userid/... | Return whether user +userid has a verified identity record for its primary email_raw address (editable by caller). |
get | /+id/is_user/... | Return whether resource +id has at least one identity of a user-defining type (auth_identity_types, default includes username_pw; requires visibility). |
get | /+id/username/... | Return the current username identity key for resource +id (requires edit permission on +id). |
get | /+id/user_info/... | Return user info map for +id with user_id, username, visited, modified, and is_expired; returns empty/default values when no username_pw identity exists (requires edit permission). |
get | /+id/logon_history/... | Return login history rows (user_agent, ip_address, created) ordered by newest first for user +id (self or admin). |
get | /+id/all_types/... | Return all identity type values present for user/resource +id; returns [] when caller cannot edit +id. |
get | /+id/all | Return all identities for user/resource +id as filtered identity records (admin only). No further lookups. |
get | /+id/all/email/... | Return all filtered email identities for user +id; ensures the resource primary email is represented as an identity when valid (requires edit permission). |
get | /+id/all/+type/... | Return filtered identity records of type +type for user/resource +id (admin only). |
get | /get/+idnid/... | Return one filtered identity record by identity id +idnid (admin only). |
get | /verify/+idnid/+verifykey/... | Return identity record +idnid only when +verifykey matches the stored verify_key using constant-time comparison; otherwise return undefined. |
get | /+id/+type/... | Return identity record for type +type on user/resource +id (admin only; enoent when missing). |
/+name marks a variable path segment. A trailing /... means extra path segments are accepted for further lookups.
See also
Summary
Types
-type bcrypt_hash() :: {bcrypt, binary()}.
-type hash() :: bcrypt_hash() | sha1_salted_hash().
-type identity() :: proplists:proplist().
-type password() :: iodata().
Functions
-spec delete_by_type(Resource, Type, Context) -> ok when Resource :: m_rsc:resource(), Type :: type(), Context :: z:context().
-spec delete_by_type_and_key(Resource, Type, Key, Context) -> ok when Resource :: m_rsc:resource(), Type :: type(), Key :: key(), Context :: z:context().
-spec delete_by_type_and_keyprefix(Resource, Type, KeyPrefix, Context) -> ok when Resource :: m_rsc:resource(), Type :: type(), KeyPrefix :: key(), Context :: z:context().
-spec delete_username(UserId, Context) -> ok | {error, Reason} when UserId :: m_rsc:resource() | undefined, Context :: z:context(), Reason :: eacces | enoent.
-spec ensure_username_pw(UserId, Context) -> ok | {error, term()} when UserId :: m_rsc:resource(), Context :: z:context().
-spec ensure_username_pw(UserId, Username, Context) -> ok | {error, term()} when UserId :: m_rsc:resource(), Username :: binary() | undefined, Context :: z:context().
-spec flush(RscId, Context) -> ok when RscId :: m_rsc:resource_id(), Context :: z:context().
-spec generate_username(RscId, Context) -> Username when RscId :: m_rsc:resource(), Context :: z:context(), Username :: binary().
-spec get(IdnId, Context) -> Identity | undefined when IdnId :: non_neg_integer(), Context :: z:context(), Identity :: proplists:proplist().
-spec get_rsc(RscId, Context) -> Identities when RscId :: m_rsc:resource(), Context :: z:context(), Identities :: [proplists:proplist()].
-spec get_rsc(RscId, Type, Context) -> Identity | undefined when RscId :: m_rsc:resource_id(), Type :: type(), Context :: z:context(), Identity :: proplists:proplist().
-spec get_rsc_by_type(RscId, Type, Context) -> Identities when RscId :: m_rsc:resource(), Type :: type(), Context :: z:context(), Identities :: [proplists:proplist()].
-spec get_rsc_by_type_key(RscId, Type, Key, Context) -> Identities when RscId :: m_rsc:resource(), Type :: type(), Key :: key(), Context :: z:context(), Identities :: [proplists:proplist()].
-spec get_rsc_by_type_keyprefix(RscId, Type, KeyPrefix, Context) -> Identities when RscId :: m_rsc:resource(), Type :: type(), KeyPrefix :: key(), Context :: z:context(), Identities :: [proplists:proplist()].
-spec get_user_info(RscId, Context) -> UserInfo when RscId :: m_rsc:resource(), Context :: z:context(), UserInfo :: #{binary() => term()}.
-spec get_username(RscId, Context) -> Username | undefined when RscId :: m_rsc:resource(), Context :: z:context(), Username :: binary().
-spec hash(password()) -> bcrypt_hash().
-spec insert(Rsc, Type, Key, Context) -> {ok, IdnId} | {error, Reason} when Rsc :: m_rsc:resource(), Type :: type(), Key :: key(), Context :: z:context(), IdnId :: pos_integer(), Reason :: invalid_key.
-spec insert(Rsc, Type, Key, Props, Context) -> {ok, IdnId} | {error, Reason} when Rsc :: m_rsc:resource(), Type :: type(), Key :: key(), Props :: proplists:proplist(), Context :: z:context(), IdnId :: pos_integer(), Reason :: invalid_key.
-spec insert_single(m_rsc:resource(), type(), key(), z:context()) -> {ok, pos_integer()} | {error, invalid_key}.
-spec is_user(RscId, Context) -> boolean() when RscId :: m_rsc:resource(), Context :: z:context().
-spec is_verified(m_rsc:resource_id(), z:context()) -> boolean().
-spec logon_history(m_rsc:resource_id(), z:context()) -> {ok, [{UserAgent, IpAddress, Created}]} | {error, eacces} when UserAgent :: binary(), IpAddress :: binary(), Created :: calendar:datetime().
-spec m_get(list(), zotonic_model:opt_msg(), z:context()) -> zotonic_model:return().
-spec merge(WinnerId, LoserId, Context) -> ok | {error, term()} when WinnerId :: m_rsc:resource(), LoserId :: m_rsc:resource(), Context :: z:context().
-spec reset_password(UserId, Context) -> ok | {error, Reason} when UserId :: m_rsc:resource(), Context :: z:context(), Reason :: enoent | eacces | nouser.
-spec set_by_type(RscId, Type, Key, Context) -> ok when RscId :: m_rsc:resource_id(), Type :: type(), Key :: key(), Context :: z:context().
-spec set_by_type(RscId, Type, Key, PropB, Context) -> ok when RscId :: m_rsc:resource_id(), Type :: type(), Key :: key(), PropB :: term(), Context :: z:context().
-spec set_expired(UserId, DateTime, Context) -> ok | {error, enoent} when UserId :: m_rsc:resource_id(), DateTime :: undefined | boolean() | calendar:datetime(), Context :: z:context().
-spec set_identity_expired(IdnId, DateTime, Context) -> ok | {error, enoent} when IdnId :: pos_integer(), DateTime :: undefined | boolean() | calendar:datetime(), Context :: z:context().
-spec set_propb(IdnId, PropB, Context) -> ok | {error, enoent} when IdnId :: pos_integer(), PropB :: undefined | term(), Context :: z:context().
-spec set_username(UserId, Username, Context) -> ok | {error, Reason} when UserId :: m_rsc:resource() | undefined, Username :: binary() | string(), Context :: z:context(), Reason :: eacces | enoent | eexist.
-spec set_verified(IdnId, Context) -> ok | {error, notfound} when IdnId :: pos_integer(), Context :: z:context().
-spec set_verified(m_rsc:resource_id(), type(), key(), z:context()) -> ok | {error, term()}.
-spec set_verify_key(IdnId, Context) -> {ok, VerifyKey} | {error, enoent} when IdnId :: pos_integer(), Context :: z:context(), VerifyKey :: binary().
-spec set_visited(m_rsc:resource_id(), z:context()) -> ok | {error, enoent}.
-spec verify_primary_email(RscId, Context) -> {ok, Status} | {error, Reason} when RscId :: m_rsc:resource(), Context :: z:context(), Status :: sent | verified, Reason :: term().