roomdb

package
v2.0.6 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2021 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package roomdb implements all the persisted database needs of the room server. This includes authentication, allow/deny list managment, invite and alias creation and also the notice content for the CMS.

The interfaces defined here are implemented twice. Once in SQLite for production and once as mocks for testing, generated by counterfeiter (https://github.com/maxbrunsfeld/counterfeiter).

See the package documentation of roomdb/sqlite for how to update it. It's important not to use the types generated by sqlboiler (sqlite/models) in the argument and return values of the interfaces here. This would leak details of the internal implementation of the roomdb/sqlite package and we want to have full control over how these interfaces can be used.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("roomdb: object not found")

ErrNotFound is returned by the admin db if an object couldn't be found.

Functions

This section is empty.

Types

type Alias

type Alias struct {
	ID int64

	Name string // or "alias string" as the docs call it

	Feed refs.FeedRef // the ssb identity that belongs to the user

	Signature []byte
}

Alias is how the roomdb stores an alias.

type AliasesService

type AliasesService interface {
	// Resolve returns all the relevant information for that alias or an error if it doesnt exist
	Resolve(context.Context, string) (Alias, error)

	// GetByID returns the alias for that ID or an error
	GetByID(context.Context, int64) (Alias, error)

	// List returns a list of all registerd aliases
	List(ctx context.Context) ([]Alias, error)

	// Register receives an alias and signature for it. Validation needs to happen before this.
	Register(ctx context.Context, alias string, userFeed refs.FeedRef, signature []byte) error

	// Revoke removes an alias from the system
	Revoke(ctx context.Context, alias string) error
}

AliasesService manages alias handle registration and lookup

type AuthFallbackService

type AuthFallbackService interface {

	// Check receives the username and password (in clear) and checks them accordingly.
	// Login might be a registered alias or a ssb id who belongs to a member.
	// If it's a valid combination it returns the user ID, or an error if they are not.
	auth.Auther

	// SetPassword creates or updates a fallback login password for this user.
	SetPassword(_ context.Context, memberID int64, password string) error

	// CreateResetToken returns a token which can be used via SetPasswordWithToken() to reset the password of a member.
	CreateResetToken(_ context.Context, createdByMember, forMember int64) (string, error)

	// SetPasswordWithToken consumes a token created with CreateResetToken() and updates the password for that member accordingly.
	SetPasswordWithToken(_ context.Context, resetToken string, password string) error
}

AuthFallbackService allows password authentication which might be helpful for scenarios where one lost access to his ssb device or key.

type AuthWithSSBService

type AuthWithSSBService interface {

	// CreateToken is used to generate a token that is stored inside a cookie.
	// It is used after a valid solution for a challenge was provided.
	CreateToken(ctx context.Context, memberID int64) (string, error)

	// CheckToken checks if the passed token is still valid and returns the member id if so
	CheckToken(ctx context.Context, token string) (int64, error)

	// RemoveToken removes a single token from the database
	RemoveToken(ctx context.Context, token string) error

	// WipeTokensForMember deletes all tokens currently held for that member
	WipeTokensForMember(ctx context.Context, memberID int64) error
}

AuthWithSSBService defines utility functions for the challenge/response system of sign-in with ssb They are particualarly of service to check valid sessions (after the client provided a solution for a challenge) And to log out valid sessions from the clients device.

type DBFeedRef

type DBFeedRef struct{ refs.FeedRef }

DBFeedRef wraps a feed reference and implements the SQL marshaling interfaces.

func (*DBFeedRef) Scan

func (r *DBFeedRef) Scan(src interface{}) error

Scan implements https://pkg.go.dev/database/sql#Scanner to read strings into feed references.

func (DBFeedRef) Value

func (r DBFeedRef) Value() (driver.Value, error)

Value returns feed references as strings to the database. https://pkg.go.dev/database/sql/driver#Valuer

type DeniedKeysService

type DeniedKeysService interface {
	// Add adds the feed to the list, together with a comment for other members
	Add(ctx context.Context, ref refs.FeedRef, comment string) error

	// HasFeed returns true if a feed is on the list.
	HasFeed(context.Context, refs.FeedRef) bool

	// HasID returns true if a member id is on the list.
	HasID(context.Context, int64) bool

	// GetByID returns the list entry for that ID or an error
	GetByID(context.Context, int64) (ListEntry, error)

	// List returns a list of all the feeds.
	List(context.Context) ([]ListEntry, error)

	// Count returns the total number of denied keys.
	Count(context.Context) (uint, error)

	// RemoveFeed removes the feed from the list.
	RemoveFeed(context.Context, refs.FeedRef) error

	// RemoveID removes the feed for the ID from the list.
	RemoveID(context.Context, int64) error
}

DeniedKeysService changes the lists of public keys that are not allowed to get into the room

type ErrAliasTaken

type ErrAliasTaken struct {
	Name string
}

func (ErrAliasTaken) Error

func (e ErrAliasTaken) Error() string

type ErrAlreadyAdded

type ErrAlreadyAdded struct {
	Ref refs.FeedRef
}

func (ErrAlreadyAdded) Error

func (aa ErrAlreadyAdded) Error() string

type Invite

type Invite struct {
	ID int64

	CreatedBy Member
	CreatedAt time.Time
}

Invite is a combination of an invite id, who created it and when. The token itself is only visible from the db.Create function and stored hashed in the database

type InvitesService

type InvitesService interface {
	// Create creates a new invite for a new member. It returns the token or an error.
	// createdBy is user ID of the admin or moderator who created it. MemberID -1 is allowed if Privacy Mode is set to Open.
	// aliasSuggestion is optional (empty string is fine) but can be used to disambiguate open invites. (See https://github.com/ssb-ngi-pointer/rooms2/issues/21)
	Create(ctx context.Context, createdBy int64) (string, error)

	// Consume checks if the passed token is still valid.
	// If it is it adds newMember to the members of the room and invalidates the token.
	// If the token isn't valid, it returns an error.
	Consume(ctx context.Context, token string, newMember refs.FeedRef) (Invite, error)

	// GetByToken returns the Invite if one for that token exists, or an error
	GetByToken(ctx context.Context, token string) (Invite, error)

	// GetByToken returns the Invite if one for that ID exists, or an error
	GetByID(ctx context.Context, id int64) (Invite, error)

	// List returns a list of all the valid invites
	List(ctx context.Context) ([]Invite, error)

	// Count returns the total number of invites.
	Count(context.Context) (uint, error)

	// Revoke removes a active invite and invalidates it for future use.
	Revoke(ctx context.Context, id int64) error
}

InvitesService manages creation and consumption of invite tokens for joining the room.

type ListEntry

type ListEntry struct {
	ID     int64
	PubKey refs.FeedRef

	CreatedAt time.Time
	Comment   string
}

ListEntry values are returned by the DenyListServices

type Member

type Member struct {
	ID      int64
	Role    Role
	PubKey  refs.FeedRef
	Aliases []Alias
}

Member holds all the information an internal user of the room has.

type MembersService

type MembersService interface {
	// Add adds a new member
	Add(_ context.Context, pubKey refs.FeedRef, r Role) (int64, error)

	// GetByID returns the member if it exists
	GetByID(context.Context, int64) (Member, error)

	// GetByFeed returns the member if it exists
	GetByFeed(context.Context, refs.FeedRef) (Member, error)

	// List returns a list of all the members.
	List(context.Context) ([]Member, error)

	// Count returns the total number of members.
	Count(context.Context) (uint, error)

	// RemoveFeed removes the feed from the list.
	RemoveFeed(context.Context, refs.FeedRef) error

	// RemoveID removes the feed for the ID from the list.
	RemoveID(context.Context, int64) error

	// SetRole changes the role of the passed member id.
	// It will return an error if the member doesn't exist.
	// It should also return an error if call would remove the last admin,
	// since only admins can change roles doing so would leave the room in a crippled state.
	SetRole(context.Context, int64, Role) error
}

MembersService stores and retreives the list of internal users (members, mods and admins).

type Notice

type Notice struct {
	ID       int64
	Title    string
	Content  string
	Language string
}

Notice holds the title and content of a page that is user generated

type NoticesService

type NoticesService interface {
	// GetByID returns the page for that ID or an error
	GetByID(context.Context, int64) (Notice, error)

	// Save updates the passed page or creates it if it's ID is zero
	Save(context.Context, *Notice) error

	// RemoveID removes the page for that ID.
	RemoveID(context.Context, int64) error
}

NoticesService is the low level store to manage single notices

type PinnedNotice

type PinnedNotice struct {
	Name    PinnedNoticeName
	Notices []Notice
}

type PinnedNoticeName

type PinnedNoticeName string

PinnedNoticeName holds a name of a well known part of the page with a fixed location. These also double as the i18n labels.

const (
	NoticeDescription   PinnedNoticeName = "NoticeDescription"
	NoticeNews          PinnedNoticeName = "NoticeNews"
	NoticePrivacyPolicy PinnedNoticeName = "NoticePrivacyPolicy"
	NoticeCodeOfConduct PinnedNoticeName = "NoticeCodeOfConduct"
)

These are the well known names that the room page will display

func (PinnedNoticeName) String

func (n PinnedNoticeName) String() string

func (PinnedNoticeName) Valid

func (n PinnedNoticeName) Valid() bool

Valid returns true if the page name is well known.

type PinnedNotices

type PinnedNotices map[PinnedNoticeName][]Notice

func (PinnedNotices) Sorted

func (pn PinnedNotices) Sorted() SortedPinnedNotices

Sorted returns a sorted list of the map, by the key names

type PinnedNoticesService

type PinnedNoticesService interface {
	// List returns a list of all the pinned notices with their corresponding notices and languages
	List(context.Context) (PinnedNotices, error)

	// Set assigns a fixed page name to an page ID and a language to allow for multiple translated versions of the same page.
	Set(ctx context.Context, name PinnedNoticeName, id int64) error

	// Get returns a single notice for a name and a language
	Get(ctx context.Context, name PinnedNoticeName, language string) (*Notice, error)
}

PinnedNoticesService allows an admin to assign Notices to specific placeholder pages. like updates, privacy policy, code of conduct

type PrivacyMode

type PrivacyMode uint
const (
	ModeUnknown PrivacyMode = iota
	ModeOpen
	ModeCommunity
	ModeRestricted
)

PrivacyMode describes the access mode the room server is currently running under. ModeOpen allows anyone to create an room invite ModeCommunity restricts invite creation to pre-existing room members (i.e. "internal users") ModeRestricted only allows admins and moderators to create room invitations

func ParsePrivacyMode

func ParsePrivacyMode(val string) PrivacyMode

func (PrivacyMode) IsValid

func (pm PrivacyMode) IsValid() error

func (*PrivacyMode) Scan

func (pm *PrivacyMode) Scan(src interface{}) error

Scan implements https://pkg.go.dev/database/sql#Scanner to read integers into a privacy mode

func (PrivacyMode) String

func (i PrivacyMode) String() string

func (PrivacyMode) Value

func (pm PrivacyMode) Value() (driver.Value, error)

Value returns privacy mode references as int64 to the database. https://pkg.go.dev/database/sql/driver#Valuer

type Role

type Role uint

Role describes the authorization level of an internal user (or member). Valid roles are Member, Moderator or Admin. The zero value Uknown is used to detect missing initializion while not falling into a bad default.

const (
	RoleUnknown Role = iota
	RoleMember
	RoleModerator
	RoleAdmin
)

func (Role) IsValid

func (r Role) IsValid() error

func (Role) String

func (i Role) String() string

func (*Role) UnmarshalText

func (r *Role) UnmarshalText(text []byte) error

UnmarshalText checks if a string is a valid role

type RoomConfig

type RoomConfig interface {
	GetPrivacyMode(context.Context) (PrivacyMode, error)
	SetPrivacyMode(context.Context, PrivacyMode) error
	GetDefaultLanguage(context.Context) (string, error)
	SetDefaultLanguage(context.Context, string) error
}

type SortedPinnedNotices

type SortedPinnedNotices []PinnedNotice

func (SortedPinnedNotices) Len

func (byName SortedPinnedNotices) Len() int

func (SortedPinnedNotices) Less

func (byName SortedPinnedNotices) Less(i, j int) bool

func (SortedPinnedNotices) Swap

func (byName SortedPinnedNotices) Swap(i, j int)

Directories

Path Synopsis
Code generated by counterfeiter.
Code generated by counterfeiter.
Package sqlite implements the SQLite backend of the roomdb interfaces.
Package sqlite implements the SQLite backend of the roomdb interfaces.

Jump to

Keyboard shortcuts

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