Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions cmd/akash/cmd/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package cmd

import (
"fmt"
"strconv"
"time"

"github.com/golang-jwt/jwt/v5"
"github.com/spf13/cobra"

sdkclient "github.com/cosmos/cosmos-sdk/client"

ajwt "github.com/akash-network/akash-api/go/util/jwt"
)

const (
FlagJWTExp = "exp"
FlagJWTNbf = "nbf"
FlagJWTAccess = "access"
FlagJWTScope = "scope"
)

func AuthCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "auth",
}

cmd.AddCommand(authJWTCmd())

return cmd
}

func authJWTCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "jwt",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cctx, err := sdkclient.GetClientTxContext(cmd)
if err != nil {
return err
}

signer := ajwt.NewSigner(cctx.Keyring, cctx.FromAddress)

now := time.Now()
nbf := now

expString, err := cmd.Flags().GetString(FlagJWTExp)
if err != nil {
return err
}

var exp time.Time
// first, attempt to parse expiration value as duration.
// fallback to unix timestamp if fails
dur, err := time.ParseDuration(expString)
if err != nil {
expInt, err := strconv.ParseInt(expString, 10, 64)
if err != nil {
return err
}

exp = time.Unix(expInt, 0)
} else {
exp = now.Add(dur)
}

if cmd.Flags().Changed(FlagJWTNbf) {
nbfString, err := cmd.Flags().GetString(FlagJWTNbf)
if err != nil {
return err
}

// first, attempt to parse expiration value as duration.
// fallback to unix timestamp if fails
dur, err := time.ParseDuration(nbfString)
if err != nil {
nbfInt, err := strconv.ParseInt(nbfString, 10, 64)
if err != nil {
return err
}

exp = time.Unix(nbfInt, 0)
} else {
exp = now.Add(dur)
}
}

accessString, err := cmd.Flags().GetString(FlagJWTAccess)
if err != nil {
return err
}

access, valid := parseAccess(accessString)
if !valid {
return fmt.Errorf("invalid `access` flags")
}

var scope ajwt.PermissionScopes

if cmd.Flags().Changed(FlagJWTScope) {
scopeString, err := cmd.Flags().GetString(FlagJWTAccess)
if err != nil {
return err
}

if err = scope.UnmarshalCSV(scopeString); err != nil {
return err
}
}

if !exp.After(now) {
return fmt.Errorf("`exp` value is invalid or in the past. expected %d (exp) > %d (curr)", exp.Unix(), now.Unix())
}

if !nbf.After(exp) {
return fmt.Errorf("`nbf` value is invalid. expected %d (nbf) < %d (exp)", nbf.Unix(), exp.Unix())
}

claims := ajwt.Claims{
RegisteredClaims: jwt.RegisteredClaims{
Issuer: cctx.FromAddress.String(),
IssuedAt: jwt.NewNumericDate(now),
NotBefore: jwt.NewNumericDate(nbf),
ExpiresAt: jwt.NewNumericDate(exp),
},
Version: "v1",
Leases: ajwt.Leases{
Access: access,
Scope: scope,
},
}

tok := jwt.NewWithClaims(ajwt.SigningMethodES256K, &claims)

tokString, err := tok.SignedString(signer)
if err != nil {
return err
}

return cctx.PrintString(tokString)
},
}

cmd.Flags().String(FlagJWTExp, "15m", "Set token's `exp` field. Format is either 15m|h or unix timestamp")
cmd.Flags().String(FlagJWTNbf, "", "Set token's `nbf` field. Format is either 15m|h or unix timestamp. Empty equals to current timestamp")
cmd.Flags().String(FlagJWTAccess, "full", "Set token's `leases.access` field. Permitted values are full|scoped|granular. Default is full")
cmd.Flags().StringSlice(FlagJWTScope, nil, "Set token's `leases.scope` field. Comma separated list of scopes. Can only be set if `leases.access=scoped`. Allowed scopes are")

return cmd
}

func parseAccess(val string) (ajwt.AccessType, bool) {
res := ajwt.AccessType(val)

switch res {
case ajwt.AccessTypeFull:
case ajwt.AccessTypeScoped:
case ajwt.AccessTypeGranular:
default:
return ajwt.AccessTypeNone, false
}

return res, true
}
1 change: 1 addition & 0 deletions cmd/akash/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
ecmd.EventCmd(),
QueryCmd(),
TxCmd(),
AuthCmd(),
keys.Commands(app.DefaultHome),
genutilcli.InitCmd(app.ModuleBasics(), app.DefaultHome),
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultHome),
Expand Down
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23.0
toolchain go1.23.6

require (
github.com/akash-network/akash-api v0.0.78
github.com/akash-network/akash-api v0.0.80
github.com/blang/semver/v4 v4.0.0
github.com/boz/go-lifecycle v0.1.1
github.com/cosmos/cosmos-sdk v0.45.16
Expand Down Expand Up @@ -77,6 +77,8 @@ replace (
google.golang.org/grpc => google.golang.org/grpc v1.33.2
)

require github.com/golang-jwt/jwt/v5 v5.2.2

require (
cosmossdk.io/api v0.2.6 // indirect
cosmossdk.io/core v0.5.1 // indirect
Expand Down Expand Up @@ -189,6 +191,9 @@ require (
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tidwall/btree v1.5.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/zondax/hid v0.9.1 // indirect
github.com/zondax/ledger-go v0.14.1 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
Expand Down
9 changes: 7 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/akash-network/akash-api v0.0.78 h1:X75JgjjjL3B+nZjWWEjSq8SXRUPM2r59x/Wc0wjOx1g=
github.com/akash-network/akash-api v0.0.78/go.mod h1:SpY0xGhmCu6Nz/M5MsKIyJUwzw2FBKR3yAeawUcBlG4=
github.com/akash-network/akash-api v0.0.80 h1:qbdhk7jdd0YsnmyOs7y+lyRKfOUm3MUhM+qBkMwL89Q=
github.com/akash-network/akash-api v0.0.80/go.mod h1:SpY0xGhmCu6Nz/M5MsKIyJUwzw2FBKR3yAeawUcBlG4=
github.com/akash-network/cometbft v0.34.27-akash.3 h1:ObmkKrMybIuRLPcwPwUMJ8Pllsr+Gsve443mkJsonMA=
github.com/akash-network/cometbft v0.34.27-akash.3/go.mod h1:BcCbhKv7ieM0KEddnYXvQZR+pZykTKReJJYf7YC7qhw=
github.com/akash-network/cosmos-sdk v0.45.16-akash.3 h1:QiHOQ1ACzCvAEXRlzGNQhp9quWLOowE104D0uESGrEk=
Expand Down Expand Up @@ -411,6 +411,8 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand Down Expand Up @@ -1030,8 +1032,11 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
Expand Down