Skip to content

Commit 14b6a6e

Browse files
committed
initial version
1 parent b6ea26d commit 14b6a6e

15 files changed

+511
-1
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.task
2+
dist
3+
log
4+
jwt-cli

.goreleaser.yml

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
before:
2+
hooks:
3+
- go get
4+
builds:
5+
- env:
6+
- CGO_ENABLED=0
7+
ldflags:
8+
- -X github.com/sgaunet/jwt-cli/cmd.version={{.Version}}
9+
goos:
10+
- linux
11+
- darwin
12+
goarch:
13+
- amd64
14+
- arm
15+
- arm64
16+
goarm:
17+
- "6"
18+
- "7"
19+
id: lin
20+
hooks:
21+
post:
22+
- upx "{{ .Path }}"
23+
- env:
24+
- CGO_ENABLED=0
25+
ldflags:
26+
- -X main.version={{.Version}}
27+
goos:
28+
- windows
29+
goarch:
30+
- amd64
31+
- arm
32+
- arm64
33+
goarm:
34+
- "6"
35+
- "7"
36+
id: win
37+
38+
archives:
39+
- name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
40+
format: binary
41+
42+
checksum:
43+
name_template: 'checksums.txt'
44+
snapshot:
45+
name_template: "{{ .Tag }}"
46+
changelog:
47+
sort: asc
48+
filters:
49+
exclude:
50+
- '^docs:'
51+
- '^test:'
52+
53+
brews:
54+
- homepage: 'https://github.com/sgaunet/homebrew-tools'
55+
folder: Formula
56+
commit_author:
57+
name: sgaunet
58+
59+
tap:
60+
owner: sgaunet
61+
name: homebrew-tools
62+
63+
64+
dockers:
65+
# https://goreleaser.com/customization/docker/
66+
- use: buildx
67+
goos: linux
68+
goarch: amd64
69+
image_templates:
70+
- "sgaunet/{{ .ProjectName }}:{{ .Version }}-amd64"
71+
- "sgaunet/{{ .ProjectName }}:latest-amd64"
72+
build_flag_templates:
73+
- "--platform=linux/amd64"
74+
- "--label=org.opencontainers.image.created={{.Date}}"
75+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
76+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
77+
- "--label=org.opencontainers.image.version={{.Version}}"
78+
# extra_files:
79+
# - src
80+
# - resources
81+
82+
- use: buildx
83+
goos: linux
84+
goarch: arm64
85+
image_templates:
86+
- "sgaunet/{{ .ProjectName }}:{{ .Version }}-arm64v8"
87+
- "sgaunet/{{ .ProjectName }}:latest-arm64v8"
88+
build_flag_templates:
89+
- "--platform=linux/arm64/v8"
90+
- "--label=org.opencontainers.image.created={{.Date}}"
91+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
92+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
93+
- "--label=org.opencontainers.image.version={{.Version}}"
94+
# extra_files:
95+
# - src
96+
# - resources
97+
98+
- use: buildx
99+
goos: linux
100+
goarch: arm
101+
goarm: "6"
102+
image_templates:
103+
- "sgaunet/{{ .ProjectName }}:{{ .Version }}-armv6"
104+
- "sgaunet/{{ .ProjectName }}:latest-armv6"
105+
build_flag_templates:
106+
- "--platform=linux/arm/v6"
107+
- "--label=org.opencontainers.image.created={{.Date}}"
108+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
109+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
110+
- "--label=org.opencontainers.image.version={{.Version}}"
111+
# extra_files:
112+
# - src
113+
# - resources
114+
115+
- use: buildx
116+
goos: linux
117+
goarch: arm
118+
goarm: "7"
119+
image_templates:
120+
- "sgaunet/{{ .ProjectName }}:{{ .Version }}-armv7"
121+
- "sgaunet/{{ .ProjectName }}:latest-armv7"
122+
build_flag_templates:
123+
- "--platform=linux/arm/v7"
124+
- "--label=org.opencontainers.image.created={{.Date}}"
125+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
126+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
127+
- "--label=org.opencontainers.image.version={{.Version}}"
128+
# extra_files:
129+
# - src
130+
# - resources
131+
132+
docker_manifests:
133+
# https://goreleaser.com/customization/docker_manifest/
134+
- name_template: sgaunet/{{ .ProjectName }}:{{ .Version }}
135+
image_templates:
136+
- sgaunet/{{ .ProjectName }}:{{ .Version }}-amd64
137+
- sgaunet/{{ .ProjectName }}:{{ .Version }}-arm64v8
138+
- sgaunet/{{ .ProjectName }}:{{ .Version }}-armv6
139+
- sgaunet/{{ .ProjectName }}:{{ .Version }}-armv7
140+
- name_template: sgaunet/{{ .ProjectName }}:latest
141+
image_templates:
142+
- sgaunet/{{ .ProjectName }}:latest-amd64
143+
- sgaunet/{{ .ProjectName }}:latest-arm64v8
144+
- sgaunet/{{ .ProjectName }}:latest-armv6
145+
- sgaunet/{{ .ProjectName }}:latest-armv7

Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FROM scratch
2+
COPY jwt-cli /jwt-cli

README.md

+59-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,60 @@
11
# jwt-cli
2-
jwt-cli is a tool to encode/decode JWT token
2+
3+
jwt-cli is a utility to encode/decode JWT token.
4+
5+
```
6+
Tool to encode/decode JWT token
7+
8+
Usage:
9+
jwt-cli [command]
10+
11+
Available Commands:
12+
completion Generate the autocompletion script for the specified shell
13+
decode decode JWT token
14+
encode encode JWT token
15+
help Help about any command
16+
methods print list of signing methods
17+
version print version of jwt-cli
18+
19+
Flags:
20+
-h, --help help for jwt-cli
21+
--m string Signing Method
22+
--s string JWT secret
23+
24+
Use "jwt-cli [command] --help" for more information about a command.
25+
```
26+
27+
Supported methods are actually:
28+
29+
* HS256
30+
* HS384
31+
* HS512
32+
33+
34+
# Install
35+
36+
## Option 1
37+
38+
* Download the release
39+
* Install the binary in /usr/local/bin
40+
41+
## Option 2: With brew
42+
43+
```
44+
brew tap sgaunet/tools
45+
brew install jwt-cli
46+
```
47+
48+
# Development
49+
50+
This project is using :
51+
52+
* golang 1.19+
53+
* [task for development](https://taskfile.dev/#/)
54+
* docker
55+
* [docker buildx](https://github.com/docker/buildx)
56+
* docker manifest
57+
* [goreleaser](https://goreleaser.com/)
58+
59+
The docker image is only created to simplify the copy of jwt-cli in another docker image.
60+

Taskfile.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# https://taskfile.dev
2+
version: '3'
3+
vars:
4+
BINFILE: jwt-cli
5+
6+
tasks:
7+
default:
8+
cmds:
9+
- CGO_ENABLED=0 go build .
10+
- upx -q {{.BINFILE}}
11+
# silent: true
12+
method: checksum
13+
generates:
14+
- "{{.BINFILE}}"
15+
16+
snapshot:
17+
cmds:
18+
- GITLAB_TOKEN="" goreleaser --clean --snapshot
19+
20+
release:
21+
cmds:
22+
- GITLAB_TOKEN="" goreleaser --clean

cmd/decode.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/sgaunet/jwt-cli/pkg/app"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// decodeCmd represents the decode command
12+
var decodeCmd = &cobra.Command{
13+
Use: "decode",
14+
Short: "decode JWT token",
15+
Long: `decode JWT token`,
16+
Run: func(cmd *cobra.Command, args []string) {
17+
err := CheckArguments(secret, token, method)
18+
if err != nil {
19+
fmt.Fprintln(os.Stderr, err.Error())
20+
os.Exit(1)
21+
}
22+
payload, err := app.DecodeJWT([]byte(secret), method, token)
23+
if err != nil {
24+
fmt.Println(err)
25+
os.Exit(1)
26+
}
27+
fmt.Println(payload)
28+
},
29+
}

cmd/encode.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/sgaunet/jwt-cli/pkg/app"
8+
9+
"github.com/spf13/cobra"
10+
)
11+
12+
// encodeCmd represents the encode command
13+
var encodeCmd = &cobra.Command{
14+
Use: "encode",
15+
Short: "encode JWT token",
16+
Long: `encode JWT token`,
17+
Run: func(cmd *cobra.Command, args []string) {
18+
err := CheckArguments(secret, token, method)
19+
if err != nil {
20+
fmt.Fprintln(os.Stderr, err.Error())
21+
os.Exit(1)
22+
}
23+
t, err := app.EncodeJWT([]byte(secret), method, payload)
24+
if err != nil {
25+
fmt.Println(err)
26+
os.Exit(1)
27+
}
28+
fmt.Println(t)
29+
},
30+
}

cmd/methods.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cmd
2+
3+
import (
4+
"os"
5+
6+
"github.com/sgaunet/jwt-cli/pkg/app"
7+
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// methodsCmd represents the methods command
12+
var methodsCmd = &cobra.Command{
13+
Use: "methods",
14+
Short: "print list of signing methods",
15+
Long: `print list of signing methods`,
16+
Run: func(cmd *cobra.Command, args []string) {
17+
app.PrintMethod(os.Stdout)
18+
},
19+
}

cmd/misc.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package cmd
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/sgaunet/jwt-cli/pkg/app"
8+
)
9+
10+
func CheckArguments(secret, token, method string) error {
11+
if secret == "" {
12+
return errors.New("secret is required")
13+
}
14+
// if token == "" {
15+
// return errors.New("token is required")
16+
// }
17+
if method == "" {
18+
return errors.New("method is required")
19+
}
20+
_, err := app.GetSigningMethod(method)
21+
if err != nil {
22+
return fmt.Errorf("invalid signing method: %v", err.Error())
23+
}
24+
return nil
25+
}

cmd/root.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package cmd
2+
3+
import (
4+
"os"
5+
6+
"github.com/spf13/cobra"
7+
)
8+
9+
var secret, token, payload, method string
10+
11+
// rootCmd represents the base command when called without any subcommands
12+
var rootCmd = &cobra.Command{
13+
Use: "jwt-cli",
14+
Short: "Tool to encode/decode JWT token",
15+
Long: `Tool to encode/decode JWT token`,
16+
// Uncomment the following line if your bare application
17+
// has an action associated with it:
18+
// Run: func(cmd *cobra.Command, args []string) { },
19+
}
20+
21+
func Execute() {
22+
err := rootCmd.Execute()
23+
if err != nil {
24+
os.Exit(1)
25+
}
26+
}
27+
28+
func init() {
29+
rootCmd.PersistentFlags().StringVar(&secret, "s", "", "JWT secret")
30+
rootCmd.PersistentFlags().StringVar(&method, "m", "", "Signing Method ")
31+
32+
rootCmd.AddCommand(encodeCmd)
33+
encodeCmd.Flags().StringVar(&payload, "p", "", "payload")
34+
rootCmd.AddCommand(decodeCmd)
35+
decodeCmd.Flags().StringVar(&token, "t", "", "token")
36+
rootCmd.AddCommand(methodsCmd)
37+
}

0 commit comments

Comments
 (0)