Documentation ¶
Overview ¶
Package data is used to store and fetch data about the irc environment.
It comes in two major pieces; State and Store. These are the main types that provide access to all others.
State ¶
State is the state about the irc world. Who is online, in what channel, what modes are on the channel or user, what topic is set. All of this information is readable (not writeable) using State. This is per-network data, so each network has it's own State database.
When using state the important types are: User and Channel. These types provide you with the information about the entities themselves. Relationships like the modes a user has on a channel are retrieved by special helpers. Examples follow.
// The client's personal information is stored in the Self instance. mynick := state.selfUser.Nick() state.EachChannel(func (ch *Channel) { fmt.Println(ch.Name) }) user := state.GetUser("nick!user@host") //Can look up by host or nick. if user != nil { fmt.Println(user) }
Store ¶
Store is about writing persisted data, and authenticating stored entities. Store is interested in persisting two types of objects: StoredChannels and StoredUsers. Both types embed a JSONStorer to store extension-specific data and can be used in any way that's desireable by extensions to persist their data across sessions.
StoredChannel is simply a JSONStorer with the channel and network ID to separate it in the key value database. JSONStorer is a map that can be used directly or using the marshalling helpers PutJSON and GetJSON.
sc := NewStoredChannel(networkID, "#channelname") // Store an array err := sc.JSONPut("myfriends", []string{"happy", "go", "lucky"}) store.SaveChannel(sc) // Retrieve the array sc = store.FindChannel(networkID, "#channelname") var array []string found, err := sc.JSONGet("myfriends", &array)
StoredUser in addition to it's JSONStorer interface, has a multi-tiered user access scheme. There is the potential for a global level, for each network, and for each channel to have it's own Access that defines a set of permissions (level and flags). These permissions cascade down so that when querying the permissions of the channel, the global and network permissions will also be present. These permissions are protected by a username and crypted password as well as optional whitelist host masks. The Store can authenticate against all of these credentials, see Authentication section below.
su := store.FindUser("username") // Check some permissions hasGoodEnoughLevel := su.HasChannelLevel(networkID, "#channelname", 100) global := su.GetGlobal() fmt.Println(global.HasFlags("abc")) // Write some permissions su.GrantGlobalFlags("abc") su.RevokeChannelFlags(networkID, "#channelname", "a") // Must save afterwards. store.SaveUser(su)
Authentication is done by the store for users in order to become "authed" and succeed in subsequent GetAuthedUser() calls, a user must succeed in an AuthUser call providing the username and password as well a host to bind this authentication to. Use this system by calling the functions: AuthUser, GetAuthedUser, Logout.
Index ¶
- Constants
- Variables
- func MemStoreProvider() (*kv.DB, error)
- type Access
- func (a *Access) ClearAllFlags()
- func (a *Access) ClearFlag(flag rune)
- func (a *Access) ClearFlags(flags ...string)
- func (a *Access) FromProto(proto *api.Access)
- func (a *Access) HasFlag(flag rune) bool
- func (a *Access) HasFlags(flags ...string) bool
- func (a *Access) HasLevel(level uint8) bool
- func (a *Access) IsZero() bool
- func (a *Access) SetAccess(level uint8, flags ...string)
- func (a *Access) SetFlag(flag rune)
- func (a *Access) SetFlags(flags ...string)
- func (a Access) String() (str string)
- func (a Access) ToProto() *api.Access
- type AuthError
- type AuthFailure
- type Channel
- func (c *Channel) AddBan(ban string)
- func (c *Channel) Bans() []string
- func (c *Channel) Clone() *Channel
- func (c *Channel) DeleteBan(ban string)
- func (c *Channel) DeleteBans(mask irc.Host)
- func (c *Channel) HasBan(ban string) bool
- func (c *Channel) IsBanned(host irc.Host) bool
- func (c *Channel) SetBans(bans []string)
- func (c *Channel) String() string
- func (c *Channel) ToProto() *api.StateChannel
- type ChannelModes
- func (m *ChannelModes) Addresses(mode rune) []string
- func (m *ChannelModes) Apply(modestring string) ([]userMode, []userMode)
- func (m *ChannelModes) ApplyDiff(d *ModeDiff)
- func (m *ChannelModes) Arg(mode rune) string
- func (m *ChannelModes) Clone() ChannelModes
- func (c *ChannelModes) FromProto(proto *api.ChannelModes) error
- func (m *ChannelModes) IsSet(modestrs ...string) bool
- func (c ChannelModes) MarshalJSON() ([]byte, error)
- func (m ChannelModes) Mode(symbol rune) rune
- func (m *ChannelModes) Set(modestrs ...string)
- func (m *ChannelModes) String() string
- func (m ChannelModes) Symbol(mode rune) rune
- func (c ChannelModes) ToProto() *api.ChannelModes
- func (c *ChannelModes) UnmarshalJSON(b []byte) error
- func (m *ChannelModes) Unset(modestrs ...string)
- type DbProvider
- type JSONStorer
- type ModeDiff
- func (d *ModeDiff) Apply(modestring string) ([]userMode, []userMode)
- func (d *ModeDiff) Clone() ModeDiff
- func (m ModeDiff) FromProto(proto *api.ModeKinds) error
- func (d *ModeDiff) IsSet(modestrs ...string) bool
- func (d *ModeDiff) IsUnset(modestrs ...string) bool
- func (m ModeDiff) MarshalJSON() ([]byte, error)
- func (m ModeDiff) Mode(symbol rune) rune
- func (d *ModeDiff) String() string
- func (m ModeDiff) Symbol(mode rune) rune
- func (m ModeDiff) ToProto() *api.ModeKinds
- func (m ModeDiff) UnmarshalJSON(b []byte) error
- type Provider
- type Self
- type State
- func (s *State) Channel(channel string) (Channel, bool)
- func (s *State) Channels() []string
- func (s *State) ChannelsByUser(nickorhost string) []string
- func (s *State) EachChannel(fn func(Channel) bool)
- func (s *State) EachUser(fn func(User) bool)
- func (s *State) IsOn(nickorhost, channel string) bool
- func (s *State) NChannels() int
- func (s *State) NChannelsByUser(nickorhost string) (n int, ok bool)
- func (s *State) NUsers() int
- func (s *State) NUsersByChannel(channel string) (n int, ok bool)
- func (s *State) Self() Self
- func (s *State) SetNetworkInfo(ni *irc.NetworkInfo) error
- func (s *State) Update(ev *irc.Event) (update StateUpdate)
- func (s *State) User(nickorhost string) (User, bool)
- func (s *State) UserModes(nickorhost, channel string) (UserModes, bool)
- func (s *State) Users() []string
- func (s *State) UsersByChannel(channel string) []string
- type StateUpdate
- type Store
- func (s *Store) AuthUserPerma(network, host, username, password string) (*StoredUser, error)
- func (s *Store) AuthUserTmp(network, host, username, password string) (*StoredUser, error)
- func (s *Store) AuthedUser(network, host string) *StoredUser
- func (s *Store) ChanUsers(network, channel string) ([]*StoredUser, error)
- func (s *Store) Channels() ([]*StoredChannel, error)
- func (s *Store) Close() error
- func (s *Store) FindChannel(netID, name string) (channel *StoredChannel, err error)
- func (s *Store) FindUser(username string) (user *StoredUser, err error)
- func (s *Store) GlobalUsers() ([]*StoredUser, error)
- func (s *Store) HasAny() (has bool, err error)
- func (s *Store) Logout(network, host string)
- func (s *Store) LogoutByUsername(username string)
- func (s *Store) NetworkUsers(network string) ([]*StoredUser, error)
- func (s *Store) RemoveChannel(netID, name string) (removed bool, err error)
- func (s *Store) RemoveUser(username string) (removed bool, err error)
- func (s *Store) SaveChannel(sc *StoredChannel) error
- func (s *Store) SaveUser(ua *StoredUser) error
- func (s *Store) Update(network string, update StateUpdate)
- type StoredChannel
- type StoredUser
- func (s *StoredUser) AddMask(mask string) bool
- func (s *StoredUser) Clone() *StoredUser
- func (s *StoredUser) FromProto(proto *api.StoredUser)
- func (s *StoredUser) GetAccess(network, channel string) (Access, bool)
- func (s *StoredUser) Grant(network, channel string, level uint8, flags ...string)
- func (s *StoredUser) Has(network, channel string, level uint8, flags ...string) bool
- func (s *StoredUser) HasFlags(network, channel string, flags ...string) bool
- func (s *StoredUser) HasLevel(network, channel string, level uint8) bool
- func (s *StoredUser) HasMask(mask string) (has bool)
- func (s *StoredUser) RemoveMask(mask string) (deleted bool)
- func (s *StoredUser) ResetPassword() (newpasswd string, err error)
- func (s *StoredUser) Revoke(network, channel string)
- func (s *StoredUser) RevokeAll()
- func (s *StoredUser) RevokeFlags(network, channel string, flags ...string)
- func (s *StoredUser) RevokeLevel(network, channel string)
- func (s *StoredUser) SetPassword(password string) (err error)
- func (s *StoredUser) String(network, channel string) string
- func (s *StoredUser) ToProto() *api.StoredUser
- func (s *StoredUser) VerifyPassword(password string) bool
- type User
- type UserModes
Constants ¶
const ( ARGS_NONE = 0x1 ARGS_ALWAYS = 0x2 ARGS_ONSET = 0x3 ARGS_ADDRESS = 0x4 )
The various kinds of mode-argument behavior during parsing.
const (
// BITS_IN_BYTE is to avoid pulling in unsafe and magic numbers.
BITS_IN_BYTE = 8
)
Variables ¶
var StoredUserPwdCost = bcrypt.DefaultCost
StoredUserPwdCost is the cost factor for bcrypt. It should not be set unless the reasoning is good and the consequences are known.
Functions ¶
func MemStoreProvider ¶
MemStoreProvider provides memory-only database stores.
Types ¶
type Access ¶
Access defines an access level and flags a-zA-Z for a user.
func (*Access) ClearFlags ¶
ClearFlags clears many flags at once.
type AuthError ¶
type AuthError struct { FailureType AuthFailure // contains filtered or unexported fields }
AuthError is returned when a user failure occurs (bad password etc.) during authentication.
type AuthFailure ¶
type AuthFailure int
AuthFailure is inside AuthErrors to describe why authentication failed.
const ( AuthErrBadPassword AuthFailure = iota + 1 AuthErrHostNotFound AuthErrUserNotFound )
These errors are in the AuthError. FailureType field.
type Channel ¶
type Channel struct { Name string `json:"name"` Topic string `json:"topic"` Modes ChannelModes `json:"channel_modes"` }
Channel encapsulates all the data associated with a channel.
func NewChannel ¶
NewChannel instantiates a channel object.
func (*Channel) DeleteBans ¶
DeleteBans deletes all bans that match a mask.
func (*Channel) ToProto ¶
func (c *Channel) ToProto() *api.StateChannel
ToProto converts to a protocol buffer
type ChannelModes ¶
type ChannelModes struct {
// contains filtered or unexported fields
}
ChannelModes encapsulates flag-based modestrings, setting and getting any modes and potentially using arguments as well. Some functions work with full modestrings containing both + and - characters, and some commands work with simple modestrings with are only positive or negative with the leading +/- omitted.
func NewChannelModes ¶
func NewChannelModes(m *modeKinds) ChannelModes
NewChannelModes creates an empty ChannelModes.
func (*ChannelModes) Addresses ¶
func (m *ChannelModes) Addresses(mode rune) []string
Addresses returns the addresses for the current mode. Nil if the mode is not set.
func (*ChannelModes) Apply ¶
func (m *ChannelModes) Apply(modestring string) ([]userMode, []userMode)
Apply takes a complex modestring and applies it to a an existing modeset. Assumes any modes not declared as part of ChannelModeKinds were not intended for channel and are user-targeted (therefore taking an argument) and returns them in two arrays, positive and negative modes respectively.
func (*ChannelModes) ApplyDiff ¶
func (m *ChannelModes) ApplyDiff(d *ModeDiff)
ApplyDiff applies a ModeDiff to the current modeset instance.
func (*ChannelModes) Arg ¶
func (m *ChannelModes) Arg(mode rune) string
Arg returns the argument for the current mode. Empty string if the mode is not set.
func (*ChannelModes) Clone ¶
func (m *ChannelModes) Clone() ChannelModes
Clone deep copies the ChannelModes.
func (*ChannelModes) FromProto ¶
func (c *ChannelModes) FromProto(proto *api.ChannelModes) error
FromProto turns API Structs -> ChannelModes
func (*ChannelModes) IsSet ¶
func (m *ChannelModes) IsSet(modestrs ...string) bool
IsSet checks to see if the given modes are set using simple mode strings.
func (ChannelModes) MarshalJSON ¶
func (c ChannelModes) MarshalJSON() ([]byte, error)
MarshalJSON turns ChannelModes -> JSON
func (*ChannelModes) Set ¶
func (m *ChannelModes) Set(modestrs ...string)
Set sets modes using a simple mode string.
func (*ChannelModes) String ¶
func (m *ChannelModes) String() string
String turns a ChannelModes into a simple string representation.
func (ChannelModes) ToProto ¶
func (c ChannelModes) ToProto() *api.ChannelModes
ToProto turns ChannelModes -> API Structs
func (*ChannelModes) UnmarshalJSON ¶
func (c *ChannelModes) UnmarshalJSON(b []byte) error
UnmarshalJSON turns JSON -> ChannelModes
func (*ChannelModes) Unset ¶
func (m *ChannelModes) Unset(modestrs ...string)
Unset unsets modes using a simple mode string.
type DbProvider ¶
DbProvider is a function that provides an internal database.
func MakeFileStoreProvider ¶
func MakeFileStoreProvider(filename string) DbProvider
MakeFileStoreProvider is the default way to create a store by using the filename and trying to open it.
type JSONStorer ¶
JSONStorer allows storage of normal strings and json values into a map.
func (JSONStorer) Clone ¶
func (js JSONStorer) Clone() JSONStorer
Clone does a deep copy of the JSONStorer.
func (JSONStorer) Get ¶
func (js JSONStorer) Get(key string) (string, bool)
Get gets a regular string from the map.
func (JSONStorer) GetJSON ¶
func (js JSONStorer) GetJSON(key string, intf interface{}) (bool, error)
GetJSON deserializes the value from the map and stores it in intf.
func (JSONStorer) Put ¶
func (js JSONStorer) Put(key, value string)
Put puts a regular string into the map.
func (JSONStorer) PutJSON ¶
func (js JSONStorer) PutJSON(key string, value interface{}) error
PutJSON serializes the value and stores it in the map.
type ModeDiff ¶
type ModeDiff struct {
// contains filtered or unexported fields
}
ModeDiff encapsulates a difference of modes, a combination of both positive change modes, and negative change modes.
func (*ModeDiff) Apply ¶
Apply takes a complex modestring and transforms it into a diff. Assumes any modes not declared as part of ChannelModeKinds were not intended for channel and are user-targeted (therefore taking an argument) and returns them in two arrays, positive and negative modes respectively.
func (*ModeDiff) IsUnset ¶
IsUnset checks if applying this diff will unset the given simple modestrs.
func (ModeDiff) MarshalJSON ¶
MarshalJSON turns modeKinds -> JSON
func (ModeDiff) UnmarshalJSON ¶
UnmarshalJSON turns JSON -> modeKinds
type Provider ¶
Provider can provide a state or store database upon request. Either can be nil even if requested.
type Self ¶
type Self struct { User ChannelModes }
Self is the client's user, a special case since user modes must be stored. Despite using the ChannelModes type, these are actually irc user modes that have nothing to do with channels. For example +i or +x on some networks.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State is the main data container. It represents the state on a network including all channels, users, and the client's self.
func NewState ¶
func NewState(netInfo *irc.NetworkInfo) (*State, error)
NewState creates a state from an irc.NetworkInfo instance.
func (*State) Channel ¶
Channel returns a channel by name if it exists. The bool returned is false if the channel does not exist.
func (*State) ChannelsByUser ¶
ChannelsByUser returns a string array of the channels a user is on.
func (*State) EachChannel ¶
EachChannel iterates through the channels. To stop iteration early return true from the fn function parameter.
func (*State) EachUser ¶
EachUser iterates through the users. To stop iteration early return true from the fn function parameter.
func (*State) NChannelsByUser ¶
NChannelsByUser returns the number of channels for a user in the database. The returned bool is false if the user doesn't exist.
func (*State) NUsersByChannel ¶
NUsersByChannel returns the number of users for a channel in the database. The returned bool is false if the channel doesn't exist.
func (*State) Self ¶
Self retrieves the user that the state identifies itself with. Usually the client that is using the data package.
func (*State) SetNetworkInfo ¶
func (s *State) SetNetworkInfo(ni *irc.NetworkInfo) error
SetNetworkInfo updates the network information of the state.
func (*State) Update ¶
func (s *State) Update(ev *irc.Event) (update StateUpdate)
Update uses the irc.IrcMessage to modify the database accordingly.
func (*State) User ¶
User fetches a user by nickname or host if he exists. The bool returned is false if the user does not exist.
func (*State) UserModes ¶
UserModes gets the channel modes of a nick or host for the given channel. The bool returned is false if the user or the channel does not exist.
func (*State) UsersByChannel ¶
UsersByChannel returns a string array of the users on a channel.
type StateUpdate ¶
StateUpdate is produced by the Update method to summarize the updates made to the database. Although anything can use this information it's created so it can in turn be passed into the store for processing users who have been renamed or disappeared.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is used to store StoredUser objects, and cache their lookup.
func (*Store) AuthUserPerma ¶
func (s *Store) AuthUserPerma( network, host, username, password string) (*StoredUser, error)
AuthUserPerma permanently authenticates a user. StoredUser will be not nil iff the user is found and authenticates successfully.
func (*Store) AuthUserTmp ¶
func (s *Store) AuthUserTmp( network, host, username, password string) (*StoredUser, error)
AuthUserTmp temporarily authenticates a user. StoredUser will be not nil iff the user is found and authenticates successfully.
func (*Store) AuthedUser ¶
func (s *Store) AuthedUser(network, host string) *StoredUser
AuthedUser looks up a user that was authenticated previously.
func (*Store) ChanUsers ¶
func (s *Store) ChanUsers(network, channel string) ([]*StoredUser, error)
ChanUsers gets users with access to a channel
func (*Store) Channels ¶
func (s *Store) Channels() ([]*StoredChannel, error)
Channels returns a slice of the channels found in the database.
func (*Store) FindChannel ¶
func (s *Store) FindChannel(netID, name string) (channel *StoredChannel, err error)
FindChannel looks up a channel based on name.
func (*Store) FindUser ¶
func (s *Store) FindUser(username string) (user *StoredUser, err error)
FindUser looks up a user based on username. It caches the result if found.
func (*Store) GlobalUsers ¶
func (s *Store) GlobalUsers() ([]*StoredUser, error)
GlobalUsers gets users with global access
func (*Store) LogoutByUsername ¶
LogoutByUsername logs an authenticated username out.
func (*Store) NetworkUsers ¶
func (s *Store) NetworkUsers(network string) ([]*StoredUser, error)
NetworkUsers gets users with Network access
func (*Store) RemoveChannel ¶
RemoveChannel removes a channel from the database, returns true if successful
func (*Store) RemoveUser ¶
RemoveUser removes a user from the database, returns true if successful.
func (*Store) SaveChannel ¶
func (s *Store) SaveChannel(sc *StoredChannel) error
SaveChannel saves a channel to the database.
func (*Store) SaveUser ¶
func (s *Store) SaveUser(ua *StoredUser) error
SaveUser saves a user to the database.
func (*Store) Update ¶
func (s *Store) Update(network string, update StateUpdate)
Update sets timeouts for seen and unseen users and invokes a reap on users who have expired their auth timeouts.
type StoredChannel ¶
type StoredChannel struct { NetID string `json:"netid"` Name string `json:"name"` JSONStorer `json:"data"` }
StoredChannel stores attributes for channels.
func NewStoredChannel ¶
func NewStoredChannel(netID, name string) *StoredChannel
NewStoredChannel creates a new stored channel.
func (*StoredChannel) Clone ¶
func (s *StoredChannel) Clone() *StoredChannel
Clone deep copies this StoredChannel.
func (*StoredChannel) FromProto ¶
func (s *StoredChannel) FromProto(proto *api.StoredChannel)
func (*StoredChannel) ToProto ¶
func (s *StoredChannel) ToProto() *api.StoredChannel
type StoredUser ¶
type StoredUser struct { Username string `json:"username"` Password []byte `json:"password"` Masks []string `json:"masks"` Access map[string]Access `json:"access"` JSONStorer `json:"data"` }
StoredUser provides access for a user to the bot, networks, and channels. This information is protected by a username and crypted password combo. Most of StoredUser's access-related methods require a network and a channel, but passing in blank strings to these methods allow us to set global, channel, and/or network specific access levels.
func NewStoredUser ¶
func NewStoredUser(un, pw string, masks ...string) (*StoredUser, error)
NewStoredUser requires username and password but masks are optional.
func (*StoredUser) AddMask ¶
func (s *StoredUser) AddMask(mask string) bool
AddMask adds a mask to this users list of wildcard masks. If a duplicate is given it returns false.
func (*StoredUser) Clone ¶
func (s *StoredUser) Clone() *StoredUser
func (*StoredUser) FromProto ¶
func (s *StoredUser) FromProto(proto *api.StoredUser)
func (*StoredUser) GetAccess ¶
func (s *StoredUser) GetAccess(network, channel string) (Access, bool)
GetAccess returns access using the network and channel provided. The bool returns false if the user has no explicit permissions for the level requested.
func (*StoredUser) Grant ¶
func (s *StoredUser) Grant( network, channel string, level uint8, flags ...string)
Grant sets level and flags for a user. To set more specific access provide network and channel names. A level of 0 will not set anything. Use revoke to remove the level. Empty flags will not set anything. Use revoke to remove the flags.
func (*StoredUser) Has ¶
func (s *StoredUser) Has(network, channel string, level uint8, flags ...string) bool
Has checks if a user has the given level and flags. Where his access is prioritized thusly: Global > Network > Channel
func (*StoredUser) HasFlags ¶
func (s *StoredUser) HasFlags(network, channel string, flags ...string) bool
HasFlags checks if a user has a given level of access. Where his access is prioritized thusly: Global > Network > Channel
func (*StoredUser) HasLevel ¶
func (s *StoredUser) HasLevel(network, channel string, level uint8) bool
HasLevel checks if a user has a given level of access. Where his access is prioritized thusly: Global > Network > Channel
func (*StoredUser) HasMask ¶
func (s *StoredUser) HasMask(mask string) (has bool)
HasMask checks to see if this user has the given masks.
func (*StoredUser) RemoveMask ¶
func (s *StoredUser) RemoveMask(mask string) (deleted bool)
RemoveMask deletes a mask from this users list of wildcard masks. Returns true if the mask was found and deleted.
func (*StoredUser) ResetPassword ¶
func (s *StoredUser) ResetPassword() (newpasswd string, err error)
ResetPassword generates a new random password, and sets the user's password to that.
func (*StoredUser) Revoke ¶
func (s *StoredUser) Revoke(network, channel string)
Revoke removes a user's access. To revoke more specific access provide network and channel names.
func (*StoredUser) RevokeAll ¶
func (s *StoredUser) RevokeAll()
RevokeAll removes all access from the user.
func (*StoredUser) RevokeFlags ¶
func (s *StoredUser) RevokeFlags(network, channel string, flags ...string)
RevokeFlags removes flags from the user. Leaving flags empty removes ALL flags.
func (*StoredUser) RevokeLevel ¶
func (s *StoredUser) RevokeLevel(network, channel string)
RevokeLevel removes level access.
func (*StoredUser) SetPassword ¶
func (s *StoredUser) SetPassword(password string) (err error)
SetPassword encrypts the password string, and sets the Password property.
func (*StoredUser) String ¶
func (s *StoredUser) String(network, channel string) string
String turns StoredUser's access into a user consumable format.
func (*StoredUser) ToProto ¶
func (s *StoredUser) ToProto() *api.StoredUser
func (*StoredUser) VerifyPassword ¶
func (s *StoredUser) VerifyPassword(password string) bool
VerifyPassword checks to see if the given password matches the stored password.
type User ¶
User encapsulates all the data associated with a user.
type UserModes ¶
type UserModes struct { Modes byte `json:"modes"` ModeKinds *modeKinds `json:"mode_kinds"` }
UserModes provides basic modes for users.
func NewUserModes ¶
func NewUserModes(m *modeKinds) UserModes
NewUserModes creates a new usermodes using the metadata instance for reference information.
func (*UserModes) StringSymbols ¶
StringSymbols turns user modes into a string but uses mode chars instead.