types

package
v0.16.4 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2020 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Overview

Package types provides data types for persisting objects in the databases.

Index

Constants

View Source
const (
	// ErrInternal means DB or other internal failure.
	ErrInternal = StoreError("internal")
	// ErrMalformed means the secret cannot be parsed or otherwise wrong.
	ErrMalformed = StoreError("malformed")
	// ErrFailed means authentication failed (wrong login or password, etc).
	ErrFailed = StoreError("failed")
	// ErrDuplicate means duplicate credential, i.e. non-unique login.
	ErrDuplicate = StoreError("duplicate value")
	// ErrUnsupported means an operation is not supported.
	ErrUnsupported = StoreError("unsupported")
	// ErrExpired means the secret has expired.
	ErrExpired = StoreError("expired")
	// ErrPolicy means policy violation, e.g. password too weak.
	ErrPolicy = StoreError("policy")
	// ErrCredentials means credentials like email or captcha must be validated.
	ErrCredentials = StoreError("credentials")
	// ErrUserNotFound means the user was not found.
	ErrUserNotFound = StoreError("user not found")
	// ErrTopicNotFound means the topic was not found.
	ErrTopicNotFound = StoreError("topic not found")
	// ErrNotFound means the object other then user or topic was not found.
	ErrNotFound = StoreError("not found")
	// ErrPermissionDenied means the operation is not permitted.
	ErrPermissionDenied = StoreError("denied")
	// ErrInvalidResponse means the client's response does not match server's expectation.
	ErrInvalidResponse = StoreError("invalid response")
)
View Source
const (
	// UploadStarted indicates that the upload has started but not finished yet.
	UploadStarted = iota
	// UploadCompleted indicates that the upload has completed successfully.
	UploadCompleted
	// UploadFailed indicates that the upload has failed.
	UploadFailed
)

Media handling constants

View Source
const NullValue = "\u2421"

NullValue is a Unicode DEL character which indicated that the value is being deleted.

Variables

This section is empty.

Functions

func TimeNow

func TimeNow() time.Time

TimeNow returns current wall time in UTC rounded to milliseconds.

Types

type AccessMode

type AccessMode uint

AccessMode is a definition of access mode bits.

const (
	ModeJoin    AccessMode = 1 << iota // user can join, i.e. {sub} (J:1)
	ModeRead                           // user can receive broadcasts ({data}, {info}) (R:2)
	ModeWrite                          // user can Write, i.e. {pub} (W:4)
	ModePres                           // user can receive presence updates (P:8)
	ModeApprove                        // user can approve new members or evict existing members (A:0x10, 16)
	ModeShare                          // user can invite new members (S:0x20, 32)
	ModeDelete                         // user can hard-delete messages (D:0x40, 64)
	ModeOwner                          // user is the owner (O:0x80, 128) - full access
	ModeUnset                          // Non-zero value to indicate unknown or undefined mode (:0x100, 256),

	ModeNone AccessMode = 0 // No access, requests to gain access are processed normally (N:0)

	// Normal user's access to a topic ("JRWPS", 47, 0x2F)
	ModeCPublic AccessMode = ModeJoin | ModeRead | ModeWrite | ModePres | ModeShare
	// User's subscription to 'me' and 'fnd' ("JPS", 41, 0x29)
	ModeCSelf AccessMode = ModeJoin | ModePres | ModeShare
	// Owner's subscription to a generic topic ("JRWPASDO", 255, 0xFF)
	ModeCFull AccessMode = ModeJoin | ModeRead | ModeWrite | ModePres | ModeApprove | ModeShare | ModeDelete | ModeOwner
	// Default P2P access mode ("JRWPA", 31, 0x1F)
	ModeCP2P AccessMode = ModeJoin | ModeRead | ModeWrite | ModePres | ModeApprove
	// Default Auth access mode for a user ("JRWPAS", 63, 0x3F).
	ModeCAuth AccessMode = ModeCP2P | ModeCPublic
	// Read-only access to topic ("JR", 3)
	ModeCReadOnly = ModeJoin | ModeRead
	// Access to 'sys' topic by a root user ("JRWPD", 79, 0x4F)
	ModeCSys = ModeJoin | ModeRead | ModeWrite | ModePres | ModeDelete

	// Admin: user who can modify access mode ("OA", dec: 144, hex: 0x90)
	ModeCAdmin = ModeOwner | ModeApprove
	// Sharer: flags which define user who can be notified of access mode changes ("OAS", dec: 176, hex: 0xB0)
	ModeCSharer = ModeCAdmin | ModeShare

	// Invalid mode to indicate an error
	ModeInvalid AccessMode = 0x100000

	// All possible valid bits (excluding ModeInvalid and ModeUnset) = 0xFF, 255
	ModeBitmask AccessMode = ModeJoin | ModeRead | ModeWrite | ModePres | ModeApprove | ModeShare | ModeDelete | ModeOwner
)

Various access mode constants

func (AccessMode) BetterEqual

func (grant AccessMode) BetterEqual(want AccessMode) bool

BetterEqual checks if grant mode allows all permissions requested in want mode.

func (AccessMode) BetterThan

func (grant AccessMode) BetterThan(want AccessMode) bool

BetterThan checks if grant mode allows more permissions than requested in want mode.

func (AccessMode) Delta

func (o AccessMode) Delta(n AccessMode) string

Delta between two modes as a string old.Delta(new). JRPAS -> JRWS: "+W-PA" Zero delta is an empty string ""

func (AccessMode) IsAdmin

func (m AccessMode) IsAdmin() bool

IsAdmin check if owner O or approver A flag is set.

func (AccessMode) IsApprover

func (m AccessMode) IsApprover() bool

IsApprover checks if approver A bit is set.

func (AccessMode) IsDefined

func (m AccessMode) IsDefined() bool

IsDefined checks if the mode is defined: not invalid and not unset. ModeNone is considered to be defined.

func (AccessMode) IsDeleter

func (m AccessMode) IsDeleter() bool

IsDeleter checks if user can hard-delete messages (D flag is set).

func (AccessMode) IsInvalid

func (m AccessMode) IsInvalid() bool

IsInvalid checks if mode is invalid.

func (AccessMode) IsJoiner

func (m AccessMode) IsJoiner() bool

IsJoiner checks if joiner flag J is set.

func (AccessMode) IsOwner

func (m AccessMode) IsOwner() bool

IsOwner checks if owner bit O is set.

func (AccessMode) IsPresencer

func (m AccessMode) IsPresencer() bool

IsPresencer checks if user receives presence updates (P flag set).

func (AccessMode) IsReader

func (m AccessMode) IsReader() bool

IsReader checks if reader flag R is set.

func (AccessMode) IsSharer

func (m AccessMode) IsSharer() bool

IsSharer checks if approver A or sharer S or owner O flag is set.

func (AccessMode) IsWriter

func (m AccessMode) IsWriter() bool

IsWriter checks if allowed to publish (writer flag W is set).

func (AccessMode) IsZero

func (m AccessMode) IsZero() bool

IsZero checks if no flags are set.

func (AccessMode) MarshalJSON

func (m AccessMode) MarshalJSON() ([]byte, error)

MarshalJSON converts AccessMode to a quoted string.

func (AccessMode) MarshalText

func (m AccessMode) MarshalText() ([]byte, error)

MarshalText converts AccessMode to ASCII byte slice.

func (*AccessMode) Scan

func (m *AccessMode) Scan(val interface{}) error

Scan is an implementation of sql.Scanner interface. It expects the value to be a byte slice representation of an ASCII string.

func (AccessMode) String

func (m AccessMode) String() string

String returns string representation of AccessMode.

func (*AccessMode) UnmarshalJSON

func (m *AccessMode) UnmarshalJSON(b []byte) error

UnmarshalJSON reads AccessMode from a quoted string.

func (*AccessMode) UnmarshalText

func (m *AccessMode) UnmarshalText(b []byte) error

UnmarshalText parses access mode string as byte slice. Does not change the mode if the string is empty or invalid.

func (AccessMode) Value

func (m AccessMode) Value() (driver.Value, error)

Value is an implementation of sql.driver.Valuer interface.

type Contact

type Contact struct {
	Id       string
	MatchOn  []string
	Access   DefaultAccess
	LastSeen time.Time
	Public   interface{}
}

Contact is a result of a search for connections

type Credential

type Credential struct {
	ObjHeader `bson:",inline"`
	// Credential owner
	User string
	// Verification method (email, tel, captcha, etc)
	Method string
	// Credential value - `jdoe@example.com` or `+12345678901`
	Value string
	// Expected response
	Resp string
	// If credential was successfully confirmed
	Done bool
	// Retry count
	Retries int
}

Credential hold data needed to validate and check validity of a credential like email or phone.

type DefaultAccess

type DefaultAccess struct {
	Auth AccessMode
	Anon AccessMode
}

DefaultAccess is a per-topic default access modes

func (*DefaultAccess) Scan

func (da *DefaultAccess) Scan(val interface{}) error

Scan is an implementation of Scanner interface so the value can be read from SQL DBs It assumes the value is serialized and stored as JSON

func (DefaultAccess) Value

func (da DefaultAccess) Value() (driver.Value, error)

Value implements sql's driver.Valuer interface.

type DelMessage

type DelMessage struct {
	ObjHeader   `bson:",inline"`
	Topic       string
	DeletedFor  string
	DelId       int
	SeqIdRanges []Range
}

DelMessage is a log entry of a deleted message range.

type DeviceDef

type DeviceDef struct {
	// Device registration ID
	DeviceId string
	// Device platform (iOS, Android, Web)
	Platform string
	// Last logged in
	LastSeen time.Time
	// Device language, ISO code
	Lang string
}

DeviceDef is the data provided by connected device. Used primarily for push notifications.

type FileDef

type FileDef struct {
	ObjHeader `bson:",inline"`
	// Status of upload
	Status int
	// User who created the file
	User string
	// Type of the file.
	MimeType string
	// Size of the file in bytes.
	Size int64
	// Internal file location, i.e. path on disk or an S3 blob address.
	Location string
}

FileDef is a stored record of a file upload

type Message

type Message struct {
	ObjHeader `bson:",inline"`
	DeletedAt *time.Time `json:"DeletedAt,omitempty" bson:",omitempty"`

	// ID of the hard-delete operation
	DelId int `json:"DelId,omitempty" bson:",omitempty"`
	// List of users who have marked this message as soft-deleted
	DeletedFor []SoftDelete `json:"DeletedFor,omitempty" bson:",omitempty"`
	SeqId      int
	Topic      string
	// Sender's user ID as string (without 'usr' prefix), could be empty.
	From    string
	Head    MessageHeaders `json:"Head,omitempty" bson:",omitempty"`
	Content interface{}
}

Message is a stored {data} message

type MessageHeaders

type MessageHeaders map[string]interface{}

MessageHeaders is needed to attach Scan() to.

func (*MessageHeaders) Scan

func (mh *MessageHeaders) Scan(val interface{}) error

Scan implements sql.Scanner interface.

func (MessageHeaders) Value

func (mh MessageHeaders) Value() (driver.Value, error)

Value implements sql's driver.Valuer interface.

type ObjHeader

type ObjHeader struct {
	// using string to get around rethinkdb's problems with uint64;
	// `bson:"_id"` tag is for mongodb to use as primary key '_id'
	// 'omitempty' causes mongodb automaticaly create "_id" field if field not set explicitly
	Id string `bson:"_id,omitempty"`

	CreatedAt time.Time
	UpdatedAt time.Time
	// contains filtered or unexported fields
}

ObjHeader is the header shared by all stored objects.

func (*ObjHeader) InitTimes

func (h *ObjHeader) InitTimes()

InitTimes initializes time.Time variables in the header to current time.

func (*ObjHeader) MergeTimes

func (h *ObjHeader) MergeTimes(h2 *ObjHeader)

MergeTimes intelligently copies time.Time variables from h2 to h.

func (*ObjHeader) SetUid

func (h *ObjHeader) SetUid(uid Uid)

SetUid assigns given Uid to appropriate header fields.

func (*ObjHeader) Uid

func (h *ObjHeader) Uid() Uid

Uid assigns Uid header field.

type ObjState

type ObjState int

ObjState represents information on objects state, such as an indication that User or Topic is suspended/soft-deleted.

const (
	StateOK        ObjState = 0
	StateSuspended ObjState = 10
	StateDeleted   ObjState = 20
	StateUndefined ObjState = 30
)

func NewObjState

func NewObjState(in string) (ObjState, error)

NewObjState parses string into an ObjState.

func (ObjState) MarshalJSON

func (os ObjState) MarshalJSON() ([]byte, error)

MarshalJSON converts ObjState to a quoted string.

func (*ObjState) Scan

func (os *ObjState) Scan(val interface{}) error

Scan is an implementation of sql.Scanner interface. It expects the value to be a byte slice representation of an ASCII string.

func (ObjState) String

func (os ObjState) String() string

String returns string representation of ObjState.

func (*ObjState) UnmarshalJSON

func (os *ObjState) UnmarshalJSON(b []byte) error

UnmarshalJSON reads ObjState from a quoted string.

func (ObjState) Value

func (os ObjState) Value() (driver.Value, error)

Value is an implementation of sql.driver.Valuer interface.

type QueryOpt

type QueryOpt struct {
	// Subscription query
	User            Uid
	Topic           string
	IfModifiedSince *time.Time
	// ID-based query parameters: Messages
	Since  int
	Before int
	// Common parameter
	Limit int
}

QueryOpt is options of a query, [since, before] - both ends inclusive (closed)

type Range

type Range struct {
	Low int
	Hi  int `json:"Hi,omitempty" bson:",omitempty"`
}

Range is a range of message SeqIDs. Low end is inclusive (closed), high end is exclusive (open): [Low, Hi). If the range contains just one ID, Hi is set to 0

type RangeSorter

type RangeSorter []Range

RangeSorter is a helper type required by 'sort' package.

func (RangeSorter) Len

func (rs RangeSorter) Len() int

Len is the length of the range.

func (RangeSorter) Less

func (rs RangeSorter) Less(i, j int) bool

Less is a comparator. Sort by Low ascending, then sort by Hi descending

func (RangeSorter) Normalize

func (rs RangeSorter) Normalize() RangeSorter

Normalize ranges - remove overlaps: [1..4],[2..4],[5..7] -> [1..7]. The ranges are expected to be sorted. Ranges are inclusive-inclusive, i.e. [1..3] -> 1, 2, 3.

func (RangeSorter) Swap

func (rs RangeSorter) Swap(i, j int)

Swap swaps two items in a slice.

type SoftDelete

type SoftDelete struct {
	User  string
	DelId int
}

SoftDelete is a single DB record of soft-deletetion.

type StoreError

type StoreError string

StoreError satisfies Error interface but allows constant values for direct comparison.

func (StoreError) Error

func (s StoreError) Error() string

Error is required by error interface.

type StringSlice

type StringSlice []string

StringSlice is defined so Scanner and Valuer can be attached to it.

func (*StringSlice) Scan

func (ss *StringSlice) Scan(val interface{}) error

Scan implements sql.Scanner interface.

func (StringSlice) Value

func (ss StringSlice) Value() (driver.Value, error)

Value implements sql/driver.Valuer interface.

type Subscription

type Subscription struct {
	ObjHeader `bson:",inline"`
	// User who has relationship with the topic
	User string
	// Topic subscribed to
	Topic     string
	DeletedAt *time.Time `bson:",omitempty"`

	// ID of the latest Soft-delete operation
	DelId int
	// Last SeqId reported by user as received by at least one of his sessions
	RecvSeqId int
	// Last SeqID reported read by the user
	ReadSeqId int

	// Access mode requested by this user
	ModeWant AccessMode
	// Access mode granted to this user
	ModeGiven AccessMode
	// User's private data associated with the subscription to topic
	Private interface{}
	// contains filtered or unexported fields
}

Subscription to a topic

func (*Subscription) GetDefaultAccess

func (s *Subscription) GetDefaultAccess() *DefaultAccess

GetDefaultAccess returns default access.

func (*Subscription) GetLastSeen

func (s *Subscription) GetLastSeen() time.Time

GetLastSeen returns lastSeen.

func (*Subscription) GetPublic

func (s *Subscription) GetPublic() interface{}

GetPublic reads value of public.

func (*Subscription) GetSeqId

func (s *Subscription) GetSeqId() int

GetSeqId returns seqId.

func (*Subscription) GetState

func (s *Subscription) GetState() ObjState

GetState returns topic's or user's state.

func (*Subscription) GetTouchedAt

func (s *Subscription) GetTouchedAt() time.Time

GetTouchedAt returns touchedAt.

func (*Subscription) GetUserAgent

func (s *Subscription) GetUserAgent() string

GetUserAgent returns userAgent.

func (*Subscription) GetWith

func (s *Subscription) GetWith() string

GetWith returns the other user for P2P subscriptions.

func (*Subscription) SetDefaultAccess

func (s *Subscription) SetDefaultAccess(auth, anon AccessMode)

SetDefaultAccess updates default access values.

func (*Subscription) SetLastSeenAndUA

func (s *Subscription) SetLastSeenAndUA(when *time.Time, ua string)

SetLastSeenAndUA updates lastSeen time and userAgent.

func (*Subscription) SetPublic

func (s *Subscription) SetPublic(pub interface{})

SetPublic assigns to public, otherwise not accessible from outside the package.

func (*Subscription) SetSeqId

func (s *Subscription) SetSeqId(id int)

SetSeqId sets seqId field.

func (*Subscription) SetState

func (s *Subscription) SetState(state ObjState)

SetState assigns topic's or user's state.

func (*Subscription) SetTouchedAt

func (s *Subscription) SetTouchedAt(touchedAt time.Time)

SetTouchedAt sets the value of touchedAt.

func (*Subscription) SetWith

func (s *Subscription) SetWith(with string)

SetWith sets other user for P2P subscriptions.

type Topic

type Topic struct {
	ObjHeader `bson:",inline"`

	// State of the topic: normal (ok), suspended, deleted
	State   ObjState
	StateAt *time.Time `json:"StateAt,omitempty" bson:",omitempty"`

	// Timestamp when the last message has passed through the topic
	TouchedAt time.Time

	// Use bearer token or use ACL
	UseBt bool

	// Topic owner. Could be zero
	Owner string

	// Default access to topic
	Access DefaultAccess

	// Server-issued sequential ID
	SeqId int
	// If messages were deleted, sequential id of the last operation to delete them
	DelId int

	Public interface{}

	// Indexed tags for finding this topic.
	Tags StringSlice
	// contains filtered or unexported fields
}

Topic stored in database. Topic's name is Id

func (*Topic) GetAccess

func (t *Topic) GetAccess(uid Uid) (mode AccessMode)

GetAccess returns given user's access mode.

func (*Topic) GetPrivate

func (t *Topic) GetPrivate(uid Uid) (private interface{})

GetPrivate returns given user's private value.

func (*Topic) GiveAccess

func (t *Topic) GiveAccess(uid Uid, want, given AccessMode)

GiveAccess updates access mode for the given user.

func (*Topic) SetPrivate

func (t *Topic) SetPrivate(uid Uid, private interface{})

SetPrivate updates private value for the given user.

type TopicCat

type TopicCat int

TopicCat is an enum of topic categories.

const (
	// TopicCatMe is a value denoting 'me' topic.
	TopicCatMe TopicCat = iota
	// TopicCatFnd is a value denoting 'fnd' topic.
	TopicCatFnd
	// TopicCatP2P is a a value denoting 'p2p topic.
	TopicCatP2P
	// TopicCatGrp is a a value denoting group topic.
	TopicCatGrp
	// TopicCatSys is a constant indicating a system topic.
	TopicCatSys
)

func GetTopicCat

func GetTopicCat(name string) TopicCat

GetTopicCat given topic name returns topic category.

type Uid

type Uid uint64

Uid is a database-specific record id, suitable to be used as a primary key.

const ZeroUid Uid = 0

ZeroUid is a constant representing uninitialized Uid.

func ParseP2P

func ParseP2P(p2p string) (uid1, uid2 Uid, err error)

ParseP2P extracts uids from the name of a p2p topic.

func ParseUid

func ParseUid(s string) Uid

ParseUid parses string NOT prefixed with anything

func ParseUid32

func ParseUid32(s string) Uid

ParseUid32 parses base32-encoded string into Uid

func ParseUserId

func ParseUserId(s string) Uid

ParseUserId parses user ID of the form "usrXXXXXX"

func (Uid) Compare

func (uid Uid) Compare(u2 Uid) int

Compare returns 0 if uid is equal to u2, 1 if u2 is greater than uid, -1 if u2 is smaller.

func (Uid) FndName

func (uid Uid) FndName() string

FndName generates 'fnd' topic name for the given Uid.

func (Uid) IsZero

func (uid Uid) IsZero() bool

IsZero checks if Uid is uninitialized.

func (Uid) MarshalBinary

func (uid Uid) MarshalBinary() ([]byte, error)

MarshalBinary converts Uid to byte slice.

func (*Uid) MarshalJSON

func (uid *Uid) MarshalJSON() ([]byte, error)

MarshalJSON converts Uid to double quoted ("ajjj") string.

func (*Uid) MarshalText

func (uid *Uid) MarshalText() ([]byte, error)

MarshalText converts Uid to string represented as byte slice.

func (Uid) P2PName

func (uid Uid) P2PName(u2 Uid) string

P2PName takes two Uids and generates a P2P topic name

func (Uid) PrefixId

func (uid Uid) PrefixId(prefix string) string

PrefixId converts Uid to string prefixed with the given prefix.

func (Uid) String

func (uid Uid) String() string

String converts Uid to base64 string.

func (Uid) String32

func (uid Uid) String32() string

String32 converts Uid to lowercase base32 string (suitable for file names on Windows).

func (*Uid) UnmarshalBinary

func (uid *Uid) UnmarshalBinary(b []byte) error

UnmarshalBinary reads Uid from byte slice.

func (*Uid) UnmarshalJSON

func (uid *Uid) UnmarshalJSON(b []byte) error

UnmarshalJSON reads Uid from a double quoted string.

func (*Uid) UnmarshalText

func (uid *Uid) UnmarshalText(src []byte) error

UnmarshalText reads Uid from string represented as byte slice.

func (Uid) UserId

func (uid Uid) UserId() string

UserId converts Uid to string prefixed with 'usr', like usrXXXXX

type UidGenerator

type UidGenerator struct {
	// contains filtered or unexported fields
}

UidGenerator holds snowflake and encryption paramenets. RethinkDB generates UUIDs as primary keys. Using snowflake-generated uint64 instead.

func (*UidGenerator) DecodeUid

func (ug *UidGenerator) DecodeUid(uid Uid) int64

DecodeUid takes an encrypted Uid and decrypts it into a non-negative int64. This is needed for go/sql compatibility where uint64 with high bit set is unsupported and possibly for other uses such as MySQL's recommendation for sequential primary keys.

func (*UidGenerator) EncodeInt64

func (ug *UidGenerator) EncodeInt64(val int64) Uid

EncodeInt64 takes a positive int64 and encrypts it into a Uid. This is needed for go/sql compatibility where uint64 with high bit set is unsupported and possibly for other uses such as MySQL's recommendation for sequential primary keys.

func (*UidGenerator) Get

func (ug *UidGenerator) Get() Uid

Get generates a unique weakly-encryped random-looking ID. The Uid is a unit64 with the highest bit possibly set which makes it incompatible with go's pre-1.9 sql package.

func (*UidGenerator) GetStr

func (ug *UidGenerator) GetStr() string

GetStr generates the same unique ID as Get then returns it as base64-encoded string. Slightly more efficient than calling Get() then base64-encoding the result.

func (*UidGenerator) Init

func (ug *UidGenerator) Init(workerID uint, key []byte) error

Init initialises the Uid generator

type UidSlice

type UidSlice []Uid

UidSlice is a slice of Uids sorted in ascending order.

func (*UidSlice) Add

func (us *UidSlice) Add(uid Uid) bool

Add uid to UidSlice keeping it sorted. Duplicates are ignored.

func (UidSlice) Contains

func (us UidSlice) Contains(uid Uid) bool

Contains checks if the UidSlice contains the given uid

func (*UidSlice) Rem

func (us *UidSlice) Rem(uid Uid) bool

Rem removes uid from UidSlice.

type User

type User struct {
	ObjHeader `bson:",inline"`

	State   ObjState
	StateAt *time.Time `json:"StateAt,omitempty" bson:",omitempty"`

	// Default access to user for P2P topics (used as default modeGiven)
	Access DefaultAccess

	// Last time when the user joined 'me' topic, by User Agent
	LastSeen *time.Time
	// User agent provided when accessing the topic last time
	UserAgent string

	Public interface{}

	// Unique indexed tags (email, phone) for finding this user. Stored on the
	// 'users' as well as indexed in 'tagunique'
	Tags StringSlice

	// Info on known devices, used for push notifications
	Devices map[string]*DeviceDef `bson:"__devices,skip,omitempty"`
	// Same for mongodb scheme. Ignore in other db backends if its not suitable.
	DeviceArray []*DeviceDef `json:"-" bson:"devices"`
}

User is a representation of a DB-stored user record.

Jump to

Keyboard shortcuts

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