diff --git a/NOTES.md b/NOTES.md index 3841447e3a86e55c17fdaf891918dfeee1df463e..ca0a0bb1812887cfe9f0ac05f7a5776ac9bedea4 100644 --- a/NOTES.md +++ b/NOTES.md @@ -21,23 +21,17 @@ Switch between MAIL and BULLETIN modes? MAIL commands are documented ## Things to do * Run [godoc](http://localhost:6060/) and then review where the help text is lacking. - * Missing [RESPOND] [MAIL] [SET PROMPT_EXPIRE] [SET NOREADNEW] [SET NOSHOWNEW] [SET NOPROMPT_EXPIRE] [SET READNEW] [SET SHOWNEW] [SHOW NEW] * Run this.Skew.Safe() before... each command? each write? - * Handle broadcast messages - create a broadcast table and add an expiration column. * Database * trigger to limit values for 'visibility'? + * trigger to limit values for 'alert'? * Add commands: * Commands for a local mail system? * Commands to connect to Mattermost or mastodon? * Make a spreadsheet for signups. - * Pager: - * Make "/" work for search. - * Run [VACUUM](https://www.sqlite.org/lang_vacuum.html) on the expire run. - * Notifications: - * Figure out how SHOWNEW, NOTIFY, READNEW and BRIEF work. * Permissions: * Review permission requirements for each command. - * Expire. This was created due to file storage limits. + * Expire. This was created due to file storage limits. Keep it? * Code cleanup: * Review sql queries and clean out the ones not used. * Review sql queries and find duplicates. diff --git a/batch/batch.go b/batch/batch.go index a28d0bc1571f2ebfc03a09dd9d086e426286c935..e8b65b71372f38e8f5b21dd61c794475df607e31 100644 --- a/batch/batch.go +++ b/batch/batch.go @@ -45,6 +45,8 @@ func Expire() int { rows, err := q.DeleteAllExpiredMessages(ctx) ask.CheckErr(err) + _, err = store.ExecContext(ctx, "VACUUM") + ask.CheckErr(err) fmt.Printf("Expired %d messages\n", rows) return 0 } diff --git a/folders/folders.go b/folders/folders.go index b4b918425e877a0c389e38373e2b2088564ee4d2..436e71c8c5e795efc65b6d285eb5e4a240b10f94 100644 --- a/folders/folders.go +++ b/folders/folders.go @@ -19,9 +19,6 @@ func ValidFolder(folder string) (storage.Folder, error) { return storage.Folder{}, errors.New("Unable to select the folder") } if !IsFolderReadable(correct.Name, this.User.Login) { - // TODO: Should be: - // WRITE(6,'('' You are not allowed to access folder.'')') - // WRITE(6,'('' See '',A,'' if you wish to access folder.'')') return storage.Folder{}, errors.New("Unable to select the folder") } return correct, nil @@ -51,11 +48,9 @@ func CreateFolder(options storage.CreateFolderParams) error { // ListFolder provides a list of folders that this.User has access to. func ListFolder() ([]storage.ListFolderRow, error) { - // TODO: need to check access. ctx := storage.Context() rows, err := this.Q.ListFolder(ctx) if err != nil { - // TODO: process this error a bit more to give a better error message. return []storage.ListFolderRow{}, err } return rows, nil diff --git a/pager/pager.go b/pager/pager.go index ce7d0d4c83d54cd14057a1ad89d83637c8153e29..9ecd1dbe12e1f8ed5c0b6ee573f8ab44398f0e7a 100644 --- a/pager/pager.go +++ b/pager/pager.go @@ -79,9 +79,12 @@ func Pager(content string) bool { return false } + // TODO: get '/' to work for searching. switch key { case ' ': // page down start += pageSize + case '\n', '\r': // line down + start++ case 'b': // page up start -= pageSize case 'q', 'Q': // quit diff --git a/repl/command.go b/repl/command.go index f8f59315049a50e6a232065735153b3c75c7f56a..3740e46cf11700afa029f8089064af2d4bc39f45 100644 --- a/repl/command.go +++ b/repl/command.go @@ -1134,14 +1134,66 @@ characteristics of the BULLETIN Utility. The following options are available: - ALWAYS BRIEF DEFAULT_EXPIRE EXPIRE_LIMIT - FOLDER NOALWAYS NOBRIEF NONOTIFY - NOPROMPT_EXPIRE NOREADNEW NOSHOWNEW NOSYSTEM - NOTIFY PROMPT_EXPIRE READNEW SHOWNEW - SYSTEM + ACCESS ALWAYS BRIEF DEFAULT_EXPIRE + EXPIRE_LIMIT FOLDER NOALWAYS NOBRIEF + NONOTIFY NOPROMPT_EXPIRE NOREADNEW NOSHOWNEW + NOSYSTEM NOTIFY PROMPT_EXPIRE READNEW + SHOWNEW SYSTEM `, Action: ActionSet, Commands: dclish.Commands{ + "ACCESS": { + Description: `Controls access to a private folder. A private folder can only be +selected by users who have been granted access. Only the owner of that +folder is allowed to grant access. + + Format: + SET [NO]ACCESS id-name [folder-name] + +The id-name can be one or more ids from the system Rights Database for +which access is being modified. It can also be a file name which +contains a list of ids. For more information concerning usage of +private folders, see HELP CREATE /PRIVATE. NOTE: Access is created via +ACLs. If a user's process privileges are set to override ACLs, that +user will be able to access the folder even if access has not been +granted. + +It is suggested that if you plan on granting access to many users, that +you create an id using the AUTHORIZE utility and then use the SET ACCESS +command to grant access to that id. Then, you can use the GRANT/ID +command in AUTHORIZE to grant the id to users, and this will give those +users access to the folder. This is preferred because of problems with +running into system quota when checking for acls on a file with a large +amount of acls. It is also means that you don't have to remember to +remove the access for that user from a folder if that user is removed +from the system. + +A user with BULLETIN privileges (see HELP SET PRIV) will be able to +select a protected folder regardless of the access settings. However, a +user without explicit access will not receive login notifications of new +messages, and thus will not be able to set any login flags. (NOTE: If +such a user selects such a folder and then uses SET ACCESS to grant him +or herself access, the user must reselect the folder in order for the +new access to take affect in order to be able to set login flags.)`, + Action: ActionSetAccess, + Flags: dclish.Flags{ + "/ALL": { + Description: ` Specifies that access to the folder is granted to all users. If /READ + is not specified, the folder will no longer be private. If /READ is + specified, all users will have read access, but only privileged users + will have write access (of course non-privileged users can gain access + via a later SET ACCESS command.) + + Format: + SET ACCESS /ALL [folder-name]`, + }, + "/READ": { + Description: ` Specifies that access to the folder will be limited to being able to + read the messages.`, + }, + }, + }, + "ALWAYS": { Description: `Specifies that the selected folder has the ALWAYS attribute. This causes messages in the folder to be displayed differently when logging diff --git a/repl/folders.go b/repl/folders.go index 3cd7d3586e6d53c6685de4b55912c88b94ad53a8..5b0631b375a7ba13c075c1f717e911ad83daade2 100644 --- a/repl/folders.go +++ b/repl/folders.go @@ -15,8 +15,27 @@ import ( ) // ActionIndex handles the `INDEX` command. This lists all the folders. -func ActionIndex(_ *dclish.Command) error { - // TODO: Handle flags! +func ActionIndex(cmd *dclish.Command) error { + + if cmd.Flags["/MARKED"].Set { + return errors.New("Not implemented yet") + } + if cmd.Flags["/NEW"].Set { + return errors.New("Not implemented yet") + } + if cmd.Flags["/RESTART"].Set { + return errors.New("Not implemented yet") + } + if cmd.Flags["/SEEN"].Set { + return errors.New("Not implemented yet") + } + if cmd.Flags["/UNMARKED"].Set { + return errors.New("Not implemented yet") + } + if cmd.Flags["/UNSEEN"].Set { + return errors.New("Not implemented yet") + } + rows, err := folders.ListFolder() if err != nil { return err diff --git a/repl/show.go b/repl/show.go index 4df2ec9d54a7e3985cd696d26834d8494a3eaa67..00de916bb5588c0a7c7dd39949e9187e16f38d6f 100644 --- a/repl/show.go +++ b/repl/show.go @@ -15,8 +15,8 @@ import ( ) // ActionShow handles the `SHOW` command. -func ActionShow(_ *dclish.Command) error { - this.ShowAlerts(false) +func ActionShow(cmd *dclish.Command) error { + fmt.Println(cmd.Description) return nil } @@ -96,7 +96,7 @@ func ActionShowFolder(cmd *dclish.Command) error { // ActionShowNew handles the `SHOW NEW` command. func ActionShowNew(_ *dclish.Command) error { - fmt.Println("TODO: implement ActionShowNew.") + this.ShowAlerts(false) return nil }