Unverified Commit 67eadd66 authored by Kevin Lyda's avatar Kevin Lyda
Browse files

Get SHOW USER to work

Still need to make it show last read message, not the most recent
message.  But I think all the rest is there.  The latter should
only take a SQL change - hopefully.
parent 3d14405e
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -79,8 +79,7 @@ the following files:
	* ~/.ssh/authorized_keys - key lines to let users connect to BULLETIN

To complete the installation, please enter the login, name and ssh key for
the first user.
`)
the first user.`)
	login, err := ask.GetLine("Enter login of initial user: ")
	login = strings.ToUpper(login)
	ask.CheckErr(err)
@@ -109,6 +108,7 @@ the first user.
			_, err = q.AddUser(ctx, storage.AddUserParams{
				Login:    seedMsgs[i].Login,
				Name:     seedMsgs[i].Name,
				Disabled: 1,
			})
			ask.CheckErr(err)
			userCreated[seedMsgs[i].Login] = true
+8 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ type Flag struct {
	Value       string
	Default     string
	Description string
	Set         bool
}

// Flags is the list of flags.
@@ -177,6 +178,7 @@ func (c Commands) run(words []string) error {
	}
	for flg := range cmd.Flags {
		cmd.Flags[flg].Value = cmd.Flags[flg].Default
		cmd.Flags[flg].Set = false
	}
	cmd.Args = []string{}

@@ -196,7 +198,7 @@ func (c Commands) run(words []string) error {
			if assigned {
				wordup = strings.ToUpper(flag)
			} else {
				wordup = args[i]
				wordup = strings.ToUpper(args[i])
			}
			toggleValue := "true"
			flg, ok := cmd.Flags[wordup]
@@ -213,6 +215,11 @@ func (c Commands) run(words []string) error {
				fmt.Printf("ERROR: Flag '%s' is a toggle.\n", args[i])
				return nil
			}
			if flg.Set {
				fmt.Printf("ERROR: Flag '%s' is already set.\n", args[i])
				return nil
			}
			flg.Set = true
			if flg.OptArg {
				if assigned {
					flg.Value = strings.Trim(val, "\"'")
+1 −77
Original line number Diff line number Diff line
@@ -1205,83 +1205,6 @@ characteristics of the BULLETIN Utility.
    SET option`,
		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.)

The id-name can be one or  more  ids  contained  in  the  system  Rights
Database.   This  includes  usernames  and  UICs.  A UIC that contains a
comma must be enclosed in quotes.   UICs  can  contain  wildcards,  i.e.
"[130,*]".   Note that by default, a process is given the process rights
id SYS$NODE_nodename, where nodename is the decnet nodename.   Thus,  by
specifing  this id, a folder can be restricted to a specific node, which
is useful when the folder is shared among nodes in a cluster.

Alternatively,  the  id-name  can be a filename which contains a list of
ids.  The filename should be preceeded by a "@".  If the suffix  is  not
specified, it will be assumed that the suffix is ".DIS" .

Warning

  If  a  user  logs  in after a private folder has been created but before
  being given access, and then is given  access,  any  defaults  that  the
  folder  has,  i.e. /BRIEF, /READNEW, & /NOTIFY, will not be set for that
  user. This is because if the  id  is  not  a  username,  it  becomes  an
  extremely  lengthy  operation  to check each user to see if have that id
  assigned to them.  The alternative is to set the defaults for all  users
  after  every  SET  ACCESS,  but that might cause problems with users who
  have manually reset those defaults.  The  correct  solution  requires  a
  large programming modification, which will be done in a later version.`,
				MinArgs: 1,
				MaxArgs: 1,
				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]`,
						OptArg: true,
					},
					"/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
@@ -1665,6 +1588,7 @@ have done this.`,
  Specifies to display  the latest message that was read  by the user(s)
  for the specified foldername.  If the foldername is not specified, the
	selected folder will be used.`,
						OptArg: true,
					},
					"/SINCE": {
						Description: `/SINCE=[date]
+114 −18
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ package repl

import (
	"fmt"
	"strings"

	"github.com/carlmjohnson/versioninfo"

@@ -127,33 +128,128 @@ func ActionShowPrivileges(_ *dclish.Command) error {

// ActionShowUser handles the `SHOW USER` command.
func ActionShowUser(cmd *dclish.Command) error {
	showAll := false
	if cmd.Flags["/ALL"].Value == "true" {
		showAll = true
		// TODO: Check permissions.
		fmt.Println("ERROR: No privs to use command.")
	// Parse the options.
	login := this.User.Login
	if len(cmd.Args) == 1 {
		if this.User.Admin == 0 {
			fmt.Println("ERROR: You are not an admin.")
			return nil
		}
		login = strings.ToUpper(cmd.Args[0])
	}
	if cmd.Flags["/ALL"].Set {
		if this.User.Admin == 0 {
			fmt.Println("ERROR: You are not an admin.")
			return nil
		}
		if len(cmd.Args) == 1 {
			fmt.Println("ERROR: You can't specify a user with /ALL.")
			return nil
		}
	showLogin := false
	}
	var showLogin int64
	if cmd.Flags["/LOGIN"].Value == "true" {
		// TODO: Check permissions.
		showLogin = true
		if this.User.Admin == 0 {
			fmt.Println("ERROR: You are not an admin.")
			return nil
		}
		showLogin = 1
	}
	folder := this.Folder
	if cmd.Flags["/FOLDER"].Set {
		fmt.Printf("%v\n", cmd.Flags["/FOLDER"].Value)
		if cmd.Flags["/FOLDER"].Value != "" {
		// TODO: Check permissions.
			folder = folders.FindFolder(cmd.Flags["/FOLDER"].Value)
			if folder.Name == "" {
				fmt.Println("ERROR: Folder does not exist.")
				return nil
			}
	if cmd.Flags["/FOLDER"].Value != "" {
		since, err := ParseDate(cmd.Flags["/FOLDER"].Value)
		}
	}
	/*
		TODO: need to add this.
		var since time.Time
		var err error
		if cmd.Flags["/SINCE"].Value != "" {
			if cmd.Flags["/LOGIN"].Set || cmd.Flags["/FOLDER"].Set {
				fmt.Println("ERROR: Must set /[NO]LOGIN or /FOLDER.")
				return nil
			}
			since, err = ParseDate(cmd.Flags["/SINCE"].Value)
			if err != nil {
				fmt.Println("ERROR: Invalid date specified.")
				return nil
			}
		fmt.Printf("TODO: select messages since %s.\n", since.Format("2006-05-04"))
		}
	fmt.Println("TODO: implement ActionShowUser.")
	fmt.Printf("TODO: %t %t %s.\n", showAll, showLogin, folder.Name)
	*/

	// Actually do the thing.
	ctx := storage.Context()
	if cmd.Flags["/LOGIN"].Set && cmd.Flags["/FOLDER"].Set {
		rows, err := this.Q.GetLastReadByEnabled(ctx,
			storage.GetLastReadByEnabledParams{
				Folder:   folder.Name,
				Disabled: showLogin,
			})
		if err != nil {
			fmt.Printf("ERROR: Failed to get list (%s).\n", err)
			return nil
		}
		fmt.Println("User          Folder                     Message #")
		for _, r := range rows {
			fmt.Printf("%-12s  %-25s  % 4d\n", r.Author, folder.Name, r.ID)
		}
	} else if cmd.Flags["/ALL"].Set && cmd.Flags["/FOLDER"].Set {
		rows, err := this.Q.GetLastRead(ctx, folder.Name)
		if err != nil {
			fmt.Printf("ERROR: Failed to get list (%s).\n", err)
			return nil
		}
		fmt.Println("User          Folder                     Message #")
		for _, r := range rows {
			fmt.Printf("%-12s  %-25s  % 4d\n", r.Author, folder.Name, r.ID)
		}
	} else if cmd.Flags["/FOLDER"].Set {
		r, err := this.Q.GetLastReadByUser(ctx,
			storage.GetLastReadByUserParams{
				Folder: folder.Name,
				Author: login,
			})
		if err != nil {
			fmt.Printf("ERROR: Failed to get list (%s).\n", err)
			return nil
		}
		fmt.Println("User          Folder                     Message #")
		fmt.Printf("%-12s  %-25s  % 4d\n", r.Author, folder.Name, r.ID)
	} else if cmd.Flags["/LOGIN"].Set {
		rows, err := this.Q.GetLastLoginByEnabled(ctx, showLogin)
		if err != nil {
			fmt.Printf("ERROR: Failed to get list (%s).\n", err)
			return nil
		}
		fmt.Println("User          Last Login")
		for _, r := range rows {
			fmt.Printf("%-12s  %s\n", r.Login, r.LastLogin.Format("2006-01-02 15:04:05"))
		}
	} else if cmd.Flags["/ALL"].Set {
		rows, err := this.Q.GetLastLogin(ctx)
		if err != nil {
			fmt.Printf("ERROR: Failed to get list (%s).\n", err)
			return nil
		}
		fmt.Println("User          Last Login")
		for _, r := range rows {
			fmt.Printf("%-12s  %s\n", r.Login, r.LastLogin.Format("2006-01-02 15:04:05"))
		}
	} else {
		r, err := this.Q.GetLastLoginByLogin(ctx, login)
		if err != nil {
			fmt.Printf("ERROR: Failed to get list (%s).\n", err)
			return nil
		}
		fmt.Println("User          Last Login")
		fmt.Printf("%-12s  %s\n", r.Login, r.LastLogin.Format("2006-01-02 15:04:05"))
	}
	return nil
}

+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ func (u User) String() string {
		u.Moderator,
		u.Alert,
		u.Disabled,
		u.LastLogin.Format("06-05-04 15:02:01"))
		u.LastLogin.Format("06-01-02 15:04:05"))
}

// String displays a folder (mainly used for debugging).
Loading