users

package
v0.18.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2025 License: Apache-2.0 Imports: 23 Imported by: 0

README

Users

Users service provides an HTTP API for managing users. Through this API clients are able to do the following actions:

  • register new accounts
  • login
  • manage account(s) (list, update, delete)

For in-depth explanation of the aforementioned scenarios, as well as thorough understanding of SuperMQ, please check out the official documentation.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

Variable Description Default
SMQ_USERS_LOG_LEVEL Log level for users service (debug, info, warn, error) info
SMQ_USERS_ADMIN_EMAIL Default user, created on startup admin@example.com
SMQ_USERS_ADMIN_PASSWORD Default user password, created on startup 12345678
SMQ_USERS_PASS_REGEX Password regex ^.{8,}$
SMQ_USERS_HTTP_HOST Users service HTTP host localhost
SMQ_USERS_HTTP_PORT Users service HTTP port 9002
SMQ_USERS_HTTP_SERVER_CERT Path to the PEM encoded server certificate file ""
SMQ_USERS_HTTP_SERVER_KEY Path to the PEM encoded server key file ""
SMQ_USERS_HTTP_SERVER_CA_CERTS Path to the PEM encoded server CA certificate file ""
SMQ_USERS_HTTP_CLIENT_CA_CERTS Path to the PEM encoded client CA certificate file ""
SMQ_AUTH_GRPC_URL Auth service GRPC URL localhost:8181
SMQ_AUTH_GRPC_TIMEOUT Auth service GRPC timeout 1s
SMQ_AUTH_GRPC_CLIENT_CERT Path to the PEM encoded client certificate file ""
SMQ_AUTH_GRPC_CLIENT_KEY Path to the PEM encoded client key file ""
SMQ_AUTH_GRPC_SERVER_CA_CERTS Path to the PEM encoded server CA certificate file ""
SMQ_USERS_DB_HOST Database host address localhost
SMQ_USERS_DB_PORT Database host port 5432
SMQ_USERS_DB_USER Database user supermq
SMQ_USERS_DB_PASS Database password supermq
SMQ_USERS_DB_NAME Name of the database used by the service users
SMQ_USERS_DB_SSL_MODE Database connection SSL mode (disable, require, verify-ca, verify-full) disable
SMQ_USERS_DB_SSL_CERT Path to the PEM encoded certificate file ""
SMQ_USERS_DB_SSL_KEY Path to the PEM encoded key file ""
SMQ_USERS_DB_SSL_ROOT_CERT Path to the PEM encoded root certificate file ""
SMQ_EMAIL_HOST Mail server host localhost
SMQ_EMAIL_PORT Mail server port 25
SMQ_EMAIL_USERNAME Mail server username ""
SMQ_EMAIL_PASSWORD Mail server password ""
SMQ_EMAIL_FROM_ADDRESS Email "from" address ""
SMQ_EMAIL_FROM_NAME Email "from" name ""
SMQ_PASSWORD_RESET_URL_PREFIX Password reset URL prefix http://localhost/password/reset
SMQ_PASSWORD_RESET_EMAIL_TEMPLATE Password reset email template reset-password-email.tmpl
SMQ_VERIFICATION_URL_PREFIX Verification URL prefix http://localhost/verify-email
SMQ_VERIFICATION_EMAIL_TEMPLATE Verification email template verification-email.tmpl
SMQ_USERS_ES_URL Event store URL nats://localhost:4222
SMQ_JAEGER_URL Jaeger server URL http://localhost:4318/v1/traces
SMQ_OAUTH_UI_REDIRECT_URL OAuth UI redirect URL http://localhost:9095/domains
SMQ_OAUTH_UI_ERROR_URL OAuth UI error URL http://localhost:9095/error
SMQ_USERS_DELETE_INTERVAL Interval for deleting users 24h
SMQ_USERS_DELETE_AFTER Time after which users are deleted 720h
SMQ_JAEGER_TRACE_RATIO Jaeger sampling ratio 1.0
SMQ_SEND_TELEMETRY Send telemetry to supermq call home server. true
SMQ_USERS_INSTANCE_ID SuperMQ instance ID ""

Deployment

The service itself is distributed as Docker container. Check the users service section in docker-compose file to see how service is deployed.

To start the service outside of the container, execute the following shell script:

# download the latest version of the service
git clone https://github.com/absmach/supermq

cd supermq

# compile the service
make users

# copy binary to bin
make install

# set the environment variables and run the service
SMQ_USERS_LOG_LEVEL=info \
SMQ_USERS_ADMIN_EMAIL=admin@example.com \
SMQ_USERS_ADMIN_PASSWORD=12345678 \
SMQ_USERS_PASS_REGEX="^.{8,}$" \
SMQ_USERS_HTTP_HOST=localhost \
SMQ_USERS_HTTP_PORT=9002 \
SMQ_USERS_HTTP_SERVER_CERT="" \
SMQ_USERS_HTTP_SERVER_KEY="" \
SMQ_USERS_HTTP_SERVER_CA_CERTS="" \
SMQ_USERS_HTTP_CLIENT_CA_CERTS="" \
SMQ_AUTH_GRPC_URL=localhost:8181 \
SMQ_AUTH_GRPC_TIMEOUT=1s \
SMQ_AUTH_GRPC_CLIENT_CERT="" \
SMQ_AUTH_GRPC_CLIENT_KEY="" \
SMQ_AUTH_GRPC_SERVER_CA_CERTS="" \
SMQ_USERS_DB_HOST=localhost \
SMQ_USERS_DB_PORT=5432 \
SMQ_USERS_DB_USER=supermq \
SMQ_USERS_DB_PASS=supermq \
SMQ_USERS_DB_NAME=users \
SMQ_USERS_DB_SSL_MODE=disable \
SMQ_USERS_DB_SSL_CERT="" \
SMQ_USERS_DB_SSL_KEY="" \
SMQ_USERS_DB_SSL_ROOT_CERT="" \
SMQ_EMAIL_HOST=smtp.mailtrap.io \
SMQ_EMAIL_PORT=2525 \
SMQ_EMAIL_USERNAME="18bf7f7070513" \
SMQ_EMAIL_PASSWORD="2b0d302e775b1e" \
SMQ_EMAIL_FROM_ADDRESS=from@example.com \
SMQ_EMAIL_FROM_NAME=Example \
SMQ_PASSWORD_RESET_URL_PREFIX=http://localhost:9002/password/reset \
SMQ_PASSWORD_RESET_EMAIL_TEMPLATE=docker/templates/reset-password-email.tmpl \
SMQ_VERIFICATION_URL_PREFIX=http://localhost:9002/users/verify-email \
SMQ_VERIFICATION_EMAIL_TEMPLATE=docker/templates/verification-email.tmpl \
SMQ_USERS_ES_URL=nats://localhost:4222 \
SMQ_JAEGER_URL=http://localhost:14268/api/traces \
SMQ_JAEGER_TRACE_RATIO=1.0 \
SMQ_SEND_TELEMETRY=true \
SMQ_OAUTH_UI_REDIRECT_URL=http://localhost:9095/domains \
SMQ_OAUTH_UI_ERROR_URL=http://localhost:9095/error \
SMQ_USERS_DELETE_INTERVAL=24h \
SMQ_USERS_DELETE_AFTER=720h \
SMQ_USERS_INSTANCE_ID="" \
$GOBIN/supermq-users

If SMQ_EMAIL_TEMPLATE doesn't point to any file service will function but password reset functionality will not work. The email environment variables are used to send emails with password reset link. The service expects a file in Go template format. The template should be something like this.

Setting SMQ_USERS_HTTP_SERVER_CERT and SMQ_USERS_HTTP_SERVER_KEY will enable TLS against the service. The service expects a file in PEM format for both the certificate and the key. Setting SMQ_USERS_HTTP_SERVER_CA_CERTS will enable TLS against the service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs. Setting SMQ_USERS_HTTP_CLIENT_CA_CERTS will enable TLS against the service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs.

Setting SMQ_AUTH_GRPC_CLIENT_CERT and SMQ_AUTH_GRPC_CLIENT_KEY will enable TLS against the auth service. The service expects a file in PEM format for both the certificate and the key. Setting SMQ_AUTH_GRPC_SERVER_CA_CERTS will enable TLS against the auth service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs.

Usage

For more information about service capabilities and its usage, please check out the API documentation.

Documentation

Overview

Package users contains the domain concept definitions needed to support SuperMQ users service functionality.

This package defines the core domain concepts and types necessary to handle users in the context of a SuperMQ users service. It abstracts the underlying complexities of user management and provides a structured approach to working with users.

Index

Constants

View Source
const (
	Disabled = "disabled"
	Enabled  = "enabled"
	Deleted  = "deleted"
	All      = "all"
	Unknown  = "unknown"
)

String representation of the possible status values.

View Source
const (
	Admin = "admin"
)

String representation of the possible role values.

View Source
const VerificationExpiryDuration = 24 * time.Hour

Variables

This section is empty.

Functions

func NewDeleteHandler

func NewDeleteHandler(ctx context.Context, users Repository, policyService policies.Service, domainsClient grpcDomainsV1.DomainsServiceClient, defCheckInterval, deleteAfter time.Duration, logger *slog.Logger)

Types

type Credentials

type Credentials struct {
	Username string `json:"username,omitempty"` // username or profile name
	Secret   string `json:"secret,omitempty"`   // password or token
}

type Emailer

type Emailer interface {
	// SendPasswordReset sends an email to the user with a link to reset the password.
	SendPasswordReset(To []string, user, token string) error

	// SendVerification sends an email to the user with a verification token.
	SendVerification(To []string, user, verificationToken string) error
}

Emailer wrapper around the email.

type Hasher

type Hasher interface {
	// Hash generates the hashed string from plain-text.
	Hash(string) (string, error)

	// Compare compares plain-text version to the hashed one. An error should
	// indicate failed comparison.
	Compare(string, string) error
}

Hasher specifies an API for generating hashes of an arbitrary textual content.

type MembersPage

type MembersPage struct {
	Page
	Members []User
}

MembersPage contains page related metadata as well as list of members that belong to this page.

type Metadata

type Metadata map[string]any

Metadata represents arbitrary JSON.

type Page

type Page struct {
	Total      uint64   `json:"total"`
	Offset     uint64   `json:"offset"`
	Limit      uint64   `json:"limit"`
	OnlyTotal  bool     `json:"only_total"`
	Id         string   `json:"id,omitempty"`
	Order      string   `json:"order,omitempty"`
	Dir        string   `json:"dir,omitempty"`
	Metadata   Metadata `json:"metadata,omitempty"`
	Domain     string   `json:"domain,omitempty"`
	Tag        string   `json:"tag,omitempty"`
	Permission string   `json:"permission,omitempty"`
	Status     Status   `json:"status,omitempty"`
	IDs        []string `json:"ids,omitempty"`
	Role       Role     `json:"-"`
	ListPerms  bool     `json:"-"`
	Username   string   `json:"username,omitempty"`
	FirstName  string   `json:"first_name,omitempty"`
	LastName   string   `json:"last_name,omitempty"`
	Email      string   `json:"email,omitempty"`
	Verified   bool     `json:"verified,omitempty"`
}

Page contains page metadata that helps navigation.

type Repository

type Repository interface {
	// RetrieveByID retrieves user by their unique ID.
	RetrieveByID(ctx context.Context, id string) (User, error)

	// RetrieveAll retrieves all users.
	RetrieveAll(ctx context.Context, pm Page) (UsersPage, error)

	// RetrieveByEmail retrieves user by its unique credentials.
	RetrieveByEmail(ctx context.Context, email string) (User, error)

	// RetrieveByUsername retrieves user by its unique credentials.
	RetrieveByUsername(ctx context.Context, username string) (User, error)

	// Update updates the user name and metadata.
	Update(ctx context.Context, id string, user UserReq) (User, error)

	// UpdateUsername updates the User's names.
	UpdateUsername(ctx context.Context, user User) (User, error)

	// UpdateSecret updates secret for user with given email.
	UpdateSecret(ctx context.Context, user User) (User, error)

	// UpdateEmail updates email for user with given id.
	UpdateEmail(ctx context.Context, user User) (User, error)

	// UpdateRole updates role for user with given id.
	UpdateRole(ctx context.Context, user User) (User, error)

	// UpdateVerifiedAt updates the verified time for user with given id.
	UpdateVerifiedAt(ctx context.Context, user User) (User, error)

	// ChangeStatus changes user status to enabled or disabled
	ChangeStatus(ctx context.Context, user User) (User, error)

	// Delete deletes user with given id
	Delete(ctx context.Context, id string) error

	// Searchusers retrieves users based on search criteria.
	SearchUsers(ctx context.Context, pm Page) (UsersPage, error)

	// RetrieveAllByIDs retrieves for given user IDs .
	RetrieveAllByIDs(ctx context.Context, pm Page) (UsersPage, error)

	CheckSuperAdmin(ctx context.Context, adminID string) error

	// Save persists the user account. A non-nil error is returned to indicate
	// operation failure.
	Save(ctx context.Context, user User) (User, error)

	// AddUserVerification adds new verification for given user id and email
	AddUserVerification(ctx context.Context, uv UserVerification) error

	// RetrieveVerificationToken retrieves verification token of given user id and email.
	RetrieveUserVerification(ctx context.Context, userID, email string) (UserVerification, error)

	// UpdateUserVerificationDetails update verification details for the given user id and email.
	UpdateUserVerification(ctx context.Context, uv UserVerification) error
}

type Role

type Role uint8

Role represents User role.

const (
	UserRole Role = iota
	AdminRole

	// AllRole is used for querying purposes to list users irrespective
	// of their role - both admin and user. It is never stored in the
	// database as the actual user role and should always be the largest
	// value in this enumeration.
	AllRole
)

Possible User role values.

func ToRole

func ToRole(status string) (Role, error)

ToRole converts string value to a valid User role.

func (Role) MarshalJSON

func (r Role) MarshalJSON() ([]byte, error)

func (Role) String

func (cs Role) String() string

String converts user role to string literal.

func (*Role) UnmarshalJSON

func (r *Role) UnmarshalJSON(data []byte) error

type Service

type Service interface {
	// Register creates new user. In case of the failed registration, a
	// non-nil error value is returned.
	Register(ctx context.Context, session authn.Session, user User, selfRegister bool) (User, error)

	// SendVerification sends a verification email to the user.
	SendVerification(ctx context.Context, session authn.Session) error

	// VerifyEmail verifies user's email using the verification token.
	VerifyEmail(ctx context.Context, verificationToken string) (User, error)

	// View retrieves user info for a given user ID and an authorized token.
	View(ctx context.Context, session authn.Session, id string) (User, error)

	// ViewProfile retrieves user info for a given token.
	ViewProfile(ctx context.Context, session authn.Session) (User, error)

	// ListUsers retrieves users list for a valid auth token.
	ListUsers(ctx context.Context, session authn.Session, pm Page) (UsersPage, error)

	// SearchUsers searches for users with provided filters for a valid auth token.
	SearchUsers(ctx context.Context, pm Page) (UsersPage, error)

	// Update updates the user's name and metadata.
	Update(ctx context.Context, session authn.Session, id string, user UserReq) (User, error)

	// UpdateTags updates the user's tags.
	UpdateTags(ctx context.Context, session authn.Session, id string, user UserReq) (User, error)

	// UpdateEmail updates the user's email.
	UpdateEmail(ctx context.Context, session authn.Session, id, email string) (User, error)

	// UpdateUsername updates the user's username.
	UpdateUsername(ctx context.Context, session authn.Session, id, username string) (User, error)

	// UpdateProfilePicture updates the user's profile picture.
	UpdateProfilePicture(ctx context.Context, session authn.Session, id string, usr UserReq) (User, error)

	// SendPasswordReset generates reset password link and sends it to the user via email.
	SendPasswordReset(ctx context.Context, email string) error

	// UpdateSecret updates the user's secret.
	UpdateSecret(ctx context.Context, session authn.Session, oldSecret, newSecret string) (User, error)

	// ResetSecret change users secret in reset flow.
	// token can be authentication token or secret reset token.
	ResetSecret(ctx context.Context, session authn.Session, secret string) error

	// UpdateRole updates the user's Role.
	UpdateRole(ctx context.Context, session authn.Session, user User) (User, error)

	// Enable logically enables the user identified with the provided ID.
	Enable(ctx context.Context, session authn.Session, id string) (User, error)

	// Disable logically disables the user identified with the provided ID.
	Disable(ctx context.Context, session authn.Session, id string) (User, error)

	// Delete deletes user with given ID.
	Delete(ctx context.Context, session authn.Session, id string) error

	// Identify returns the user id from the given token.
	Identify(ctx context.Context, session authn.Session) (string, error)

	// IssueToken issues a new access and refresh token when provided with either a username or email.
	IssueToken(ctx context.Context, identity, secret string) (*grpcTokenV1.Token, error)

	// RefreshToken refreshes expired access tokens.
	// After an access token expires, the refresh token is used to get
	// a new pair of access and refresh tokens.
	RefreshToken(ctx context.Context, session authn.Session, refreshToken string) (*grpcTokenV1.Token, error)

	// OAuthCallback handles the callback from any supported OAuth provider.
	// It processes the OAuth tokens and either signs in or signs up the user based on the provided state.
	OAuthCallback(ctx context.Context, user User) (User, error)

	// OAuthAddUserPolicy adds a policy to the user for an OAuth request.
	OAuthAddUserPolicy(ctx context.Context, user User) error
}

Service specifies an API that must be fullfiled by the domain service implementation, and all of its decorators (e.g. logging & metrics).

func NewService

func NewService(token grpcTokenV1.TokenServiceClient, urepo Repository, policyService policies.Service, emailer Emailer, hasher Hasher, idp supermq.IDProvider) Service

NewService returns a new Users service implementation.

type Status

type Status uint8

Status represents User status.

const (
	// EnabledStatus represents enabled User.
	EnabledStatus Status = iota
	// DisabledStatus represents disabled User.
	DisabledStatus
	// DeletedStatus represents a user that will be deleted.
	DeletedStatus

	// AllStatus is used for querying purposes to list users irrespective
	// of their status - both enabled and disabled. It is never stored in the
	// database as the actual User status and should always be the largest
	// value in this enumeration.
	AllStatus
)

Possible User status values.

func ToStatus

func ToStatus(status string) (Status, error)

ToStatus converts string value to a valid User/Group status.

func (Status) MarshalJSON

func (s Status) MarshalJSON() ([]byte, error)

Custom Marshaller for Uesr/Groups.

func (Status) String

func (s Status) String() string

String converts user/group status to string literal.

func (*Status) UnmarshalJSON

func (s *Status) UnmarshalJSON(data []byte) error

Custom Unmarshaler for User/Groups.

type User

type User struct {
	ID             string      `json:"id"`
	FirstName      string      `json:"first_name,omitempty"`
	LastName       string      `json:"last_name,omitempty"`
	Tags           []string    `json:"tags,omitempty"`
	Metadata       Metadata    `json:"metadata,omitempty"`
	Status         Status      `json:"status"`                    // 0 for enabled, 1 for disabled
	Role           Role        `json:"role"`                      // 0 for normal user, 1 for admin
	ProfilePicture string      `json:"profile_picture,omitempty"` // profile picture URL
	Credentials    Credentials `json:"credentials,omitempty"`
	Permissions    []string    `json:"permissions,omitempty"`
	Email          string      `json:"email,omitempty"`
	CreatedAt      time.Time   `json:"created_at,omitempty"`
	UpdatedAt      time.Time   `json:"updated_at,omitempty"`
	UpdatedBy      string      `json:"updated_by,omitempty"`
	VerifiedAt     time.Time   `json:"verified_at,omitempty"`
	AuthProvider   string      `json:"auth_provider,omitempty"`
}

func (User) Validate

func (u User) Validate() error

Validate returns an error if user representation is invalid.

type UserRepository

type UserRepository struct {
	DB postgres.Database
}

UserRepository struct implements the Repository interface.

type UserReq added in v0.17.0

type UserReq struct {
	FirstName      *string    `json:"first_name,omitempty"`
	LastName       *string    `json:"last_name,omitempty"`
	Metadata       *Metadata  `json:"metadata,omitempty"`
	Tags           *[]string  `json:"tags,omitempty"`
	ProfilePicture *string    `json:"profile_picture,omitempty"`
	UpdatedBy      *string    `json:"updated_by,omitempty"`
	UpdatedAt      *time.Time `json:"updated_at,omitempty"`
}

type UserVerification added in v0.18.1

type UserVerification struct {
	UserID    string    `json:"user_id"`
	Email     string    `json:"email"`
	OTP       string    `json:"otp"`
	CreatedAt time.Time `json:"-"`
	ExpiresAt time.Time `json:"-"`
	UsedAt    time.Time `json:"-"`
}

UserVerification OTP is sent to the user's email as base64 encoded with UserID, Email and OTP. It should not be exposed via API.

func NewUserVerification added in v0.18.1

func NewUserVerification(userID, email string) (UserVerification, error)

func (*UserVerification) Decode added in v0.18.1

func (u *UserVerification) Decode(data string) error

func (UserVerification) Encode added in v0.18.1

func (u UserVerification) Encode() (string, error)

func (UserVerification) Match added in v0.18.1

func (UserVerification) Valid added in v0.18.1

func (u UserVerification) Valid() error

type UsersPage

type UsersPage struct {
	Page
	Users []User
}

Directories

Path Synopsis
api
Package api contains API-related concerns: endpoint definitions, middlewares and all resource representations.
Package api contains API-related concerns: endpoint definitions, middlewares and all resource representations.
grpc
Package grpc contains implementation of Users service gRPC API.
Package grpc contains implementation of Users service gRPC API.
Package emailer contains the domain concept definitions needed to support SuperMQ users email service functionality.
Package emailer contains the domain concept definitions needed to support SuperMQ users email service functionality.
Package events provides the domain concept definitions needed to support SuperMQ users service functionality.
Package events provides the domain concept definitions needed to support SuperMQ users service functionality.
Package hasher contains the domain concept definitions needed to support SuperMQ users password hasher sub-service functionality.
Package hasher contains the domain concept definitions needed to support SuperMQ users password hasher sub-service functionality.
Package middleware provides authorization, logging, metrics and tracing middleware for SuperMQ Users Service.
Package middleware provides authorization, logging, metrics and tracing middleware for SuperMQ Users Service.
Package mocks contains mocks for testing purposes.
Package mocks contains mocks for testing purposes.
Package postgres contains the database implementation of users repository layer.
Package postgres contains the database implementation of users repository layer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL