Documentation ¶
Overview ¶
package ponder is a go language helper for RethinkDB.
Ponder implements a file-system like abstraction, with Rethinkdb tables as directories and documents stored as files, with Unix-like per document permission system. It also contains various conveniences on top of the standard driver.
Index ¶
- Constants
- func AnyToArray[Type any](array []any) []Type
- func ArrayToAny[Type any](array []Type) []any
- func CheckDocInfos(user User, needed Mode, infos []DocInfo) ([]ID, []ID)
- func CheckUserDocInfo(user User, needed Mode, qe r.QueryExecutor, multiple bool, docInfo r.Term, ...) r.Term
- func DirReadAllUnchecked[Type any](dw *DirReader, array *[]Type) (*[]Type, error)
- func DirReadUnchecked[Type any](dr *DirReader, object Type) (Type, error)
- func DirWriteAllUnchecked[Type any](dw *DirWriter, array []Type) ([]Type, error)
- func DirWriteUnchecked[Type any](dw *DirWriter, object Type) (Type, error)
- func StringsToStrings[Type interface{ ... }, Sub interface{ ... }](array []Sub) []Type
- func SystemDelete(system *System, path FileName, id ID) error
- func SystemGet[Type any](system *System, path FileName, id ID) (*Type, error)
- func SystemPut[Type any](system *System, path FileName, object *Type) (*Type, error)
- func SystemUpdate[Type any](system *System, path FileName, id ID, object *Type) (*Type, error)
- type Creds
- type Dir
- type DirReader
- func (dr *DirReader) AllUnchecked(array any) (any, error)
- func (dr *DirReader) Check(needed Mode) *DirReader
- func (dr *DirReader) Delete() error
- func (dr *DirReader) DeleteUnchecked() error
- func (dr *DirReader) Read(object any) (any, error)
- func (dr *DirReader) ReadAll(array any) (any, error)
- func (dr *DirReader) ReadJSON() (string, error)
- func (dr *DirReader) Unchecked(object any) (any, error)
- func (dr *DirReader) UncheckedJSON() (string, error)
- type DirWriter
- func (dw DirWriter) All(objects map[ID]any) ([]any, error)
- func (dw DirWriter) AllUnchecked(array []any) ([]any, error)
- func (dw *DirWriter) Check(needed Mode, objects map[ID]any) ([]DocInfo, error)
- func (dw DirWriter) JSON(id ID, jsonStr string) (any, error)
- func (dw DirWriter) One(id ID, object any) (any, error)
- func (dw DirWriter) Unchecked(object any) (any, error)
- func (dw DirWriter) UncheckedJSON(jsonStr string) (any, error)
- type Doc
- type DocInfo
- type DocInfoGetter
- type DocInfoGetterSetter
- type DocInfoSetter
- type Docs
- type Error
- type FileName
- type Group
- type Header
- type ID
- type Login
- type Mode
- type ModeMap
- type PasswordCreds
- type PasswordLogin
- type Shell
- type System
- func (s *System) Close() error
- func (s *System) DirExists(fn FileName) bool
- func (s *System) GetDocInfo(id ID) (*DocInfo, error)
- func (s *System) GetDocInfos(ids []ID) (*[]DocInfo, error)
- func (s *System) Mkdir(fn FileName, keys ...string) (*Dir, error)
- func (s *System) MkdirIfNew(fn FileName, pk ...string) (*Dir, error)
- func (s *System) Prepare() error
- func (s *System) PutDocInfo(info DocInfo) error
- func (s *System) ReadDir(fn FileName) (*Dir, error)
- func (s *System) RmDir(fn FileName) error
- func (s *System) Shell(userID ID, creds Creds) (*Shell, error)
- func (s *System) Wait() error
- func (s *System) WaitForTable(tableName string) error
- type SystemDir
- type User
Constants ¶
const DocInfoField = "_ponder_docinfo"
DocInfoField is the field used to store docinfo in
const ErrorCheckAccessDenied = Error("Check: access denied")
const ErrorDocInfoSetNil = Error("DocInfoSet: cannot set nil document info")
const ErrorPutAllIdsDoNotMatchObjects = Error("PutAll: IDs do not match objects")
const ErrorReadDirDoesNotExist = Error("ReadDir: dir does not exist")
const ErrorRmDirNotEmpty = Error("RmDir: dir is not empty")
const ErrorShellCannotLoadGroups = Error("Shell: cannot load user groups")
Variables ¶
This section is empty.
Functions ¶
func AnyToArray ¶
ArrayToAny converts an array of any to an array of Type
func ArrayToAny ¶
ArrayToAny converts an array of type Type to an array of any
func CheckDocInfos ¶
CheckDocInfos return a list of DocInfo IDs for which the check is OK, and one for which it is not ok.
func CheckUserDocInfo ¶
func CheckUserDocInfo(user User, needed Mode, qe r.QueryExecutor, multiple bool, docInfo r.Term, table r.Term) r.Term
Check fetches the docinfo using the dockinfo term and checks if the user has access with the needed mode. The docinfo selection should select the matching docinfo for the documents to load. Multiple should be set to trtue if the goal is to check multiple documents in stead of one. The function returns a term, based on table, that that will use Get or GetAll on table to return the documents the user is allowed to see. If the user cannot see any documents an error term with ErrorCheckAccessDenied is returned in stead. An error term is also returned if the fetchuing of the docinfo fails somehow.
func DirReadAllUnchecked ¶
DirReadAllUnchecked generically stores an array of Ponder objecst or document to the dir. This is a low level function that does not do any permission checks. If the object exists it will be overwritten.
func DirReadUnchecked ¶
DirReadUnchecked generically stores a Ponder object or document to the dir. This is a low level function that does not do any permission checks. If the object exists it will be overwritten.
func DirWriteAllUnchecked ¶
DirWriteAllUnchecked generically stores an array of Ponder objecst or document to the dir. This is a low level function that does not do any permission checks. If the object exists it will be overwritten.
func DirWriteUnchecked ¶
DirWriteUnchecked generically stores a Ponder object or document to the dir. This is a low level function that does not do any permission checks. If the object exists it will be overwritten.
func StringsToStrings ¶
StringsToStrings converts an array of string-likes a subtype of Type to an array of Type which must also be a sybtype of string.
Types ¶
type Creds ¶
type Creds interface { // Creds returns the credentials data as a Header Creds() Header }
Creds is an interface that models credentials a user has to present to log in to the Ponder System. PasswordCreds are provided.
type Dir ¶
type Dir struct { // system is the underlying system, inherited *System `json:"-" rethinkdb:"-"` // Virtual filename of this Dir FileName `json:"file_name" rethinkdb:"file_name"` // PK is the name of the primary key that will be used for this dir // If empty, Ponder uses "id". PK string `json:"pk,omitempty" rethinkdb:"pk,omitempty"` // Table is the table expression for this dir Table r.Term `json:"-" rethinkdb:"-"` // Shell that is using this dir. May be null if the dir is being used // by the System, and no shell is connected Shell *Shell `json:"-" rethinkdb:"-"` }
Dir is a virtual directory with documents, mapped to a rethinkdb table.
func (*Dir) All ¶
GetAll returns a DirReader for reading multiple documents. It will return all documents.
type DirReader ¶
type DirReader struct { // Dir this was derived from. *Dir `json:"-" rethinkdb:"-"` // Condition for reading. Condition r.Term `json:"-" rethinkdb:"-"` // DocInfo is the docinfo expression for this DirReader DocInfo r.Term `json:"-" rethinkdb:"-"` // Multiple is true if this reader is for reading multiple objects Multiple bool }
DirReader allows to specify read conditions easily
func (*DirReader) AllUnchecked ¶
AllUnchecked gets an array of objects from the dir with given ID. This is a low level function that does not do any permission checks. Will return an error if no results were found.
func (*DirReader) Check ¶
Check fetches the docinfo and checks if the user of Dir.Shell has access with the needed mode. If Dir.Shell is nil, this does nothing. The reader modified to become a getAll which only includes the documents to which access is allowed, possibly ending up with an empty list.
func (*DirReader) Delete ¶
Delete deletes all matches for the DirReader. This function calls Check first with ModeWrite.
func (*DirReader) DeleteUnchecked ¶
DeleteUnchecked deletes all matches for the DirReader. This is a low level function that does not do any permission checks.
func (*DirReader) Read ¶
Read gets a single object from the dir with given ID. This function calls Check first with ModeRead. Will return an error if no results were found.
func (*DirReader) ReadAll ¶
AllRead gets an array of objects from the dir with given ID. This function calls Check first with ModeRead. Will return an error if no results were found.
func (*DirReader) ReadJSON ¶
ReadJSON gets a single object from the dir with given ID. The object is converted to a JSON string. This function calls Check first with ModeRead. Will return an error if no results were found.
func (*DirReader) Unchecked ¶
Unchecked gets a single object from the dir with given ID. This is a low level function that does not do any permission checks. Will return an error if no results were found.
func (*DirReader) UncheckedJSON ¶
UncheckedJSON gets a single object from the dir with given ID. The object is converted to a JSON string. This is a low level function that does not do any permission checks. Will return an error if no results were found.
type DirWriter ¶
type DirWriter struct { // Dir this was derived from. *Dir `json:"-" rethinkdb:"-"` // Condition for writing. Condition r.Term `json:"-" rethinkdb:"-"` // Options for inserting r.InsertOpts `json:"-" rethinkdb:"-"` // DocInfo is the docinfo expression for this DirWriter DocInfo r.Term `json:"-" rethinkdb:"-"` }
DirWriter allows to specify options on writing easily.
func (DirWriter) All ¶
All writes an array of objects by ID. The IDs are needed to be able to check the permissions. This function calls Check first with ModeWrite. It also creates Docinfo for any new documents.
func (DirWriter) AllUnchecked ¶
Unchecked writes an array. This is a low level function that does not do any permission checks.
func (*DirWriter) Check ¶
Check returns an error if the write is blocked by the permissions. If the ID does not exist in the docinfo, then it is considered that the document is new, and that docinfo must be generated for it, since writing a new doc is always allowed. If Dir.Shell is nil, this does nothing.
func (DirWriter) JSON ¶
JSOM writes a single JSON string. This function calls Check first with ModeWrite. It also creates Docinfo for any new documents.
func (DirWriter) One ¶
One writes a single object. This function calls Check first with ModeWrite. It also creates Docinfo for any new documents.
type Doc ¶
type Doc interface { // Must be able to get/set documents DocInfoGetterSetter }
Doc is a document stored with Ponder which has to be checked for access with the ponder permission system.
type DocInfo ¶
type DocInfo struct { // ID of the document that this DocInfo applies to. // This is also used as the ID of the DocInfo itself // The ID should be a globally unique ID such as an UUID, ULID or URL. ID ID `json:"id" rethinkdb:"id"` // Mode of this document for users who are not a oner in users or groups. // Users and groups may have their own modes. Mode Mode `json:"mode" rethinkdb:"mode"` // Users are the IDs of the users who own this document mapped // to their Mode permissions. Users ModeMap `json:"users" rethinkdb:"users"` // Groups are the IDs of the groups who own this document mapped // to their Mode permissions. Groups ModeMap `json:"groups" rethinkdb:"groups"` // Mod is the modification time of the document. Mod time.Time `json:"mod" rethinkdb:"mod"` // Hide is the time the document was hidden, or nil if not hidden. Hide *time.Time `json:"hide" rethinkdb:"hide,omitempty"` // Header may contain extra data needed for this document. Header `json:"header,omitempty" rethinkdb:"header,omitempty"` }
DocInfo keeps track of metadata of a ponder document. This includes the permissionsm users and groups of the document. It also keeps track of time stamps and hidden status of documents.
func TermGetDocInfo ¶
TermGetDocInfo gets docinfo from a Term using an executor.
func (DocInfo) Allowed ¶
Returns wheter or not a user is allowed to perform the action indicated by mode with this document.
func (*DocInfo) DocInfoGet ¶
DocInfoGet implements DocInfoGetter for DocInfo
func (*DocInfo) DocInfoSet ¶
DocInfoSet implements DocInfoSetter for DocInfo
type DocInfoGetter ¶
type DocInfoGetter interface { // DocInfoGet returns the docinfo for this object. // May return nil to indicate it is not available. DocInfoGet() *DocInfo }
DocInfoGetter is an interface that returns the docinfo for a document.
type DocInfoGetterSetter ¶
type DocInfoGetterSetter interface { DocInfoGetter DocInfoSetter }
DocInfoGetterSetter is an interface that gets and sets the docinfo for a document.
type DocInfoSetter ¶
type DocInfoSetter interface { // DocInfoSet returns the docinfo for this object. // Should return nil on success. // This function may optionally return an error if DocInfo is nil. DocInfoSet(*DocInfo) error }
DocInfoSetter is an interface that sets the docinfo for a document.
type FileName ¶
type FileName string
FileName is used to idernify Dir and dOc by Ponder. It is a string but it shiould be Punicode-encodable.
type Group ¶
type Group struct { // ID is the group id. It can be anything but is must be globally unique ID ID `json:"id" rethinkdb:"id"` // Link is the link to your own group document. Link ID `json:"link" rethinkdb:"link"` // Header may contain extra data needed for this user. Header `json:"header,omitempty" rethinkdb:"header,omitempty"` // Custom is a field that can be used to store your own custom data Custom any `json:"custom,omitempty" rethinkdb:"custom,omitempty"` }
Group is a group who can have or not have access to a document in ponder. You can link this to the group in your own database using the UID. Ponder generates the "root" and the "nobody" groups on setup.
type Header ¶
Header is used as a catch-all for storing supplemental data in Ponder. Reuse the http Header for this.
type ID ¶
type ID string
ID is a universally unique identifier used to identify and link to various objects in Ponder. It can be anything, but it should be globally unique in the Ponder system. Therefore, a URL, UUID, or ULID, or similar could be used for this. However for User IDs or Group IDs is is often simpler to use a name.
type Login ¶
type Login interface { // CheckLogin should atttempt to log in the user with the given creds. // It should return nil if the user logged in sucessfully or an error if not. CheckLogin(user User, creds Creds) error // Write should write the login for this user, possibly using the creds. WriteLogin(user *User, creds Creds) error // DeleteLogin should delete the login info for this user, but not the user // iself. Requires creds to confirm. DeleteLogin(user *User, cred Creds) error }
Login is an interface that models a method to login a user to the System. It also allows to update the credentials of the user. As a default a PasswordLogin that uses User.Hash is provided. Custom Login methods can use the User.Headers fields to store data.
type Mode ¶
type Mode uint32
const ( // ModeSetuid can modify the users of this document. ModeSetuid Mode = 0o4000 // ModeSetgid can modify the groups of this document. ModeSetgid Mode = 0o2000 // ModeSticky documents cannot be deleted by non-owners if set in Doc.Mode. ModeSticky Mode = 0o1000 // ModeRead read the document ModeRead Mode = 0o004 // ModeWrite can write the document ModeWrite Mode = 0o002 // ModeList can list the document ModeList Mode = 0o001 )
type PasswordCreds ¶
type PasswordCreds string
PasswordCreds are password credentials.
func (PasswordCreds) Creds ¶
func (pwc PasswordCreds) Creds() Header
type PasswordLogin ¶
type PasswordLogin struct {
*System
}
PasswordLogin is a Login method that simply uses a bcrypt hash password
func (PasswordLogin) CheckLogin ¶
func (pwl PasswordLogin) CheckLogin(user User, creds Creds) error
func (PasswordLogin) DeleteLogin ¶
func (pwl PasswordLogin) DeleteLogin(user *User, creds Creds) error
func (PasswordLogin) WriteLogin ¶
func (pwl PasswordLogin) WriteLogin(user *User, creds Creds) error
type Shell ¶
type Shell struct { // System this shell is for *System `json:"system" rethinkdb:"system"` // User who is using the shell *User `json:"user" rethinkdb:"user"` // Groups of the user, cached Goups []Group `json:"groups" rethinkdb:"groups"` }
Shell is a virtual shell session on a System that limits the permissions of the logged in User to what matches their permissions and rights.
type System ¶
type System struct { // Name of the underlying database Name string `json:"name" rethinkdb:"name"` // QueryExecutor to wrap r.QueryExecutor `json:"-" rethinkdb:"-"` // Mock, if any Mock *r.Mock `json:"-" rethinkdb:"-"` // Session if any Session *r.Session `json:"-" rethinkdb:"-"` // Prefix to use for Ponder functionality, _ponder by default Prefix FileName `json:"prefix" rethinkdb:"prefix"` // SystemDir inherited. SystemDir `json:"system_dir" rethinkdb:"system_dir"` // The login to use. Set to PassordLogin by default. // Overwrite this to change the login method Login `json:"-" rethinkdb:"-"` }
System is a virtual file system and wrapper around a connection to a rethinkdb that has the convenience it might be mocked if needed. The methods of System do ignore the Ponder permission system, and all RethinkDB queries are executed zith the Rethinkdb privileges of the connected RethinkDB user. To uset he permission system use Login to obtain a Shell.
func Open ¶
Open opens a connection for a System and sets up Ponder on it. The urlstring should begin with rethinkdb:// for a real connection or rethinkdb+mock:// for a mock. The following options can be set in the query:
- ponder_prefix: prefix to use for ponder related tables, zzz_ponder default
func OpenWithoutPrepare ¶
OpenWithoutPrepare opens a connection for a System but does not set up Ponder on it. It does call Wait to wait util the database is ready.
func (*System) GetDocInfo ¶
GetDocInfo gets the docinfo for the given resource id. This can be used for permission checking or checking the modtime, etc.
func (*System) GetDocInfos ¶
GetDocInfos gets the docinfo for the given resource ids. This can be used for permission checking or checking the modtime, etc.
func (*System) Mkdir ¶
MkDir makes a dir with the given key, if any. Waits for the table to be fully created.
func (*System) MkdirIfNew ¶
MkDir makes a dir with the given primary key, if any, if it doesn't exist. Returns the dir for further use unless if there was an error.
func (*System) PutDocInfo ¶
PutDocInfo writes docinfo to the System's Doc Dir. The docinfo is used to determine the pernnissions of the document with the Id of info. Therefor it is neccerqy to use qgrlobqlly unique ID, such as a UUID, IRL or ULID.
func (*System) Shell ¶
Shell starts a shell session in the System for the given Ponder user. Inside the shell the access is limited to what the user's permissions allow.
func (*System) WaitForTable ¶ added in v0.1.3
WaitForTable waits until the named rethinkdb table is completely ready.
type SystemDir ¶
type SystemDir struct { // Doc dir Doc *Dir `json:"user" rethinkdb:"doc"` // User dir User *Dir `json:"doc" rethinkdb:"user"` // Group dir Group *Dir `json:"group" rethinkdb:"group"` // Version dir Version *Dir `json:"version" rethinkdb:"version"` }
SystemDir contains all Ponder specific Dirs
type User ¶
type User struct { // ID is the ID of the user. It can be anything but it must be globally // unique. It is also used as the login name of this user. ID ID `json:"id" rethinkdb:"id"` // Groups are the IDs of the groups to which this user belongs. Groups []ID `json:"groups" rethinkdb:"groups"` // Link is the link to your own user document. Link ID `json:"link" rethinkdb:"link"` // Header may contain extra data needed for this user. Header `json:"header,omitempty" rethinkdb:"header,omitempty"` // Root is true if this is a root user. // Root users can bypass all permissions for all Ponder documents. Root bool `json:"root" rethinkdb:"root"` // Admin is true if this is an admin user. // Admin users can bypass permissions for Ponder documents that // belong to one of the groups the admin is in, but not for // documents that they are not in the group for. Admin bool `json:"admin" rethinkdb:"admin"` // Login is the Login linked to the ponder User Login `json:"-" rethinkdb:"-"` // Custom is a field that can be used to store your own custom data Custom any `json:"custom,omitempty" rethinkdb:"custom,omitempty"` }
User is a user who can have or not have access to a document in Ponder. You can link this to the user in your own database using the UID and the Authericator interface. This is different from the RethinkDB user. Ponder generates the "root" and the "nobody" users on setup.