Files
opencloud/services/auth-app/pkg/command/create.go
2025-01-21 11:16:38 +01:00

125 lines
3.6 KiB
Go

package command
import (
"context"
"fmt"
authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
"github.com/opencloud-eu/reva/v2/pkg/auth/scope"
"time"
applicationsv1beta1 "github.com/cs3org/go-cs3apis/cs3/auth/applications/v1beta1"
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
"github.com/opencloud-eu/opencloud/pkg/registry"
"github.com/opencloud-eu/opencloud/pkg/tracing"
"github.com/opencloud-eu/opencloud/services/auth-app/pkg/config"
"github.com/opencloud-eu/opencloud/services/auth-app/pkg/config/parser"
ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
"github.com/urfave/cli/v2"
"google.golang.org/grpc/metadata"
)
// Create is the entrypoint for the app auth create command
func Create(cfg *config.Config) *cli.Command {
return &cli.Command{
Name: "create",
Usage: "create an app auth token for a user",
Category: "maintenance",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "user-name",
Value: "",
Usage: "user to create the app-token for",
},
&cli.StringFlag{
Name: "expiration",
Value: "72h",
Usage: "expiration of the app password, e.g. 72h, 1h, 1m, 1s. Default is 72h.",
},
},
Before: func(_ *cli.Context) error {
return configlog.ReturnError(parser.ParseConfig(cfg))
},
Action: func(c *cli.Context) error {
traceProvider, err := tracing.GetServiceTraceProvider(cfg.Tracing, cfg.Service.Name)
if err != nil {
return err
}
gatewaySelector, err := pool.GatewaySelector(
cfg.Reva.Address,
append(
cfg.Reva.GetRevaOptions(),
pool.WithRegistry(registry.GetRegistry()),
pool.WithTracerProvider(traceProvider),
)...)
if err != nil {
return err
}
next, err := gatewaySelector.Next()
if err != nil {
return err
}
userName := c.String("user-name")
if userName == "" {
fmt.Printf("Username to create app token for: ")
if _, err := fmt.Scanln(&userName); err != nil {
return err
}
}
ctx := context.Background()
authRes, err := next.Authenticate(ctx, &gatewayv1beta1.AuthenticateRequest{
Type: "machine",
ClientId: "username:" + userName,
ClientSecret: cfg.MachineAuthAPIKey,
})
if err != nil {
return err
}
if authRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
return fmt.Errorf("error authenticating user: %s", authRes.GetStatus().GetMessage())
}
granteeCtx := ctxpkg.ContextSetUser(context.Background(), &userpb.User{Id: authRes.GetUser().GetId()})
granteeCtx = metadata.AppendToOutgoingContext(granteeCtx, ctxpkg.TokenHeader, authRes.GetToken())
scopes, err := scope.AddOwnerScope(map[string]*authpb.Scope{})
if err != nil {
return err
}
expiry, err := time.ParseDuration(c.String("expiration"))
if err != nil {
return err
}
appPassword, err := next.GenerateAppPassword(granteeCtx, &applicationsv1beta1.GenerateAppPasswordRequest{
TokenScope: scopes,
Label: "Generated via CLI",
Expiration: &typesv1beta1.Timestamp{
Seconds: uint64(time.Now().Add(expiry).Unix()),
},
})
if err != nil {
return err
}
fmt.Printf("App token created for %s", authRes.GetUser().GetUsername())
fmt.Println()
fmt.Printf(" token: %s", appPassword.GetAppPassword().GetPassword())
fmt.Println()
return nil
},
}
}