305e7bac68
Signed-off-by: Michael Mayer <michael@photoprism.app>
113 lines
3.2 KiB
Go
113 lines
3.2 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/manifoldco/promptui"
|
|
"github.com/urfave/cli"
|
|
|
|
"github.com/photoprism/photoprism/internal/config"
|
|
"github.com/photoprism/photoprism/internal/entity"
|
|
"github.com/photoprism/photoprism/pkg/clean"
|
|
"github.com/photoprism/photoprism/pkg/report"
|
|
"github.com/photoprism/photoprism/pkg/rnd"
|
|
"github.com/photoprism/photoprism/pkg/unix"
|
|
)
|
|
|
|
// AuthAddFlags specifies the "photoprism auth add" command flags.
|
|
var AuthAddFlags = []cli.Flag{
|
|
cli.StringFlag{
|
|
Name: "name, n",
|
|
Usage: "`CLIENT` name to help identify the application",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "scope, s",
|
|
Usage: "authorization `SCOPES` e.g. \"metrics\" or \"photos albums\" (\"*\" to allow all)",
|
|
},
|
|
cli.Int64Flag{
|
|
Name: "expires, e",
|
|
Usage: "authentication `LIFETIME` in seconds, after which access expires (-1 to disable the limit)",
|
|
Value: unix.Year,
|
|
},
|
|
}
|
|
|
|
// AuthAddCommand configures the command name, flags, and action.
|
|
var AuthAddCommand = cli.Command{
|
|
Name: "add",
|
|
Usage: "Adds a new authentication secret for client applications",
|
|
Description: "If you specify a username as argument, an app password will be created for this user account." +
|
|
" It can be used as a password replacement to grant limited access to client applications.",
|
|
ArgsUsage: "[username]",
|
|
Flags: AuthAddFlags,
|
|
Action: authAddAction,
|
|
}
|
|
|
|
// authAddAction shows detailed session information.
|
|
func authAddAction(ctx *cli.Context) error {
|
|
return CallWithDependencies(ctx, func(conf *config.Config) error {
|
|
// Get username from command flag.
|
|
userName := clean.Username(ctx.Args().First())
|
|
|
|
// Find user account.
|
|
user := entity.FindUserByName(userName)
|
|
|
|
if user == nil && userName != "" {
|
|
return fmt.Errorf("user %s not found", clean.LogQuote(userName))
|
|
}
|
|
|
|
// Get client name from command flag or ask for it.
|
|
clientName := ctx.String("name")
|
|
|
|
if clientName == "" {
|
|
prompt := promptui.Prompt{
|
|
Label: "Client Name",
|
|
Default: rnd.Name(),
|
|
}
|
|
|
|
res, err := prompt.Run()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
clientName = clean.Name(res)
|
|
}
|
|
|
|
// Get auth scope from command flag or ask for it.
|
|
authScope := ctx.String("scope")
|
|
|
|
if authScope == "" {
|
|
prompt := promptui.Prompt{
|
|
Label: "Authorization Scope",
|
|
Default: "*",
|
|
}
|
|
|
|
res, err := prompt.Run()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
authScope = clean.Scope(res)
|
|
}
|
|
|
|
// Create session and show the authentication secret.
|
|
sess, err := entity.AddClientAuthentication(clientName, ctx.Int64("expires"), authScope, user)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create authentication secret: %s", err)
|
|
} else {
|
|
// Show client authentication credentials.
|
|
if sess.UserUID == "" {
|
|
fmt.Printf("\nPLEASE WRITE DOWN THE FOLLOWING RANDOMLY GENERATED ACCESS TOKEN, AS YOU WILL NOT BE ABLE TO SEE IT AGAIN:\n")
|
|
fmt.Printf("\n%s\n", report.Credentials("Access Token", sess.AuthToken(), "Authorization Scope", sess.Scope()))
|
|
} else {
|
|
fmt.Printf("\nPLEASE WRITE DOWN THE FOLLOWING RANDOMLY GENERATED APP PASSWORD, AS YOU WILL NOT BE ABLE TO SEE IT AGAIN:\n")
|
|
fmt.Printf("\n%s\n", report.Credentials("App Password", sess.AuthToken(), "Authorization Scope", sess.Scope()))
|
|
}
|
|
|
|
}
|
|
|
|
return err
|
|
})
|
|
}
|