diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..008272a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + commit-message: + prefix: "deps:" + directory: "/" + schedule: + interval: "weekly" + day: "sunday" + time: "09:00" + - package-ecosystem: "github-actions" + commit-message: + prefix: "ci:" + directory: "/" + schedule: + interval: "weekly" + day: "sunday" + time: "09:00" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..c800836 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,17 @@ +name: build + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 0 * * 0' # run "At 00:00 on Sunday" + +# See https://github.com/cristalhq/.github/.github/workflows +jobs: + build: + uses: cristalhq/.github/.github/workflows/build.yml@v0.6.0 + + vuln: + uses: cristalhq/.github/.github/workflows/vuln.yml@v0.6.0 diff --git a/GUIDE.md b/GUIDE.md new file mode 100644 index 0000000..ce94337 --- /dev/null +++ b/GUIDE.md @@ -0,0 +1 @@ +# Guide for paseto \ No newline at end of file diff --git a/README.md b/README.md index 030c087..89644b8 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ -# paseto \ No newline at end of file +# paseto + +[![build-img]][build-url] +[![pkg-img]][pkg-url] +[![reportcard-img]][reportcard-url] +[![coverage-img]][coverage-url] +[![version-img]][version-url] + +PASETO (Platform-Agnostic Security Tokens implementation) in Go [paseto](https://paseto.io). + +See also JWT in Go [cristalhq/jwt](https://github.com/cristalhq/jwt). + +## Features + +* Simple API. +* Clean and tested code. +* Optimized for speed. +* Concurrent-safe. + +See [docs][pkg-url] or [GUIDE.md](https://github.com/cristalhq/paseto/blob/main/GUIDE.md) for more details. + +## Install + +Go version 1.18+ + +``` +go get github.com/cristalhq/paseto +``` + +## Example + +```go +// TODO +``` + +See examples: [example_test.go](https://github.com/cristalhq/paseto/blob/main/example_test.go). + +## License + +[MIT License](LICENSE). + +[build-img]: https://github.com/cristalhq/paseto/workflows/build/badge.svg +[build-url]: https://github.com/cristalhq/paseto/actions +[pkg-img]: https://pkg.go.dev/badge/cristalhq/paseto +[pkg-url]: https://pkg.go.dev/github.com/cristalhq/paseto +[reportcard-img]: https://goreportcard.com/badge/cristalhq/paseto +[reportcard-url]: https://goreportcard.com/report/cristalhq/paseto +[coverage-img]: https://codecov.io/gh/cristalhq/paseto/branch/main/graph/badge.svg +[coverage-url]: https://codecov.io/gh/cristalhq/paseto +[version-img]: https://img.shields.io/github/v/release/cristalhq/paseto +[version-url]: https://github.com/cristalhq/paseto/releases diff --git a/example_test.go b/example_test.go new file mode 100644 index 0000000..149a903 --- /dev/null +++ b/example_test.go @@ -0,0 +1,5 @@ +package paseto_test + +func Example() { + // Output: +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..032d967 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module paseto + +go 1.18 diff --git a/paseto.go b/paseto.go new file mode 100644 index 0000000..7520173 --- /dev/null +++ b/paseto.go @@ -0,0 +1,83 @@ +package paseto + +import "encoding/json" + +type Token struct { + typ TokenType + raw []byte + dot1 int + dot2 int + claims json.RawMessage + footer json.RawMessage +} + +func (t Token) Type() TokenType { + return t.typ +} + +func (t *Token) String() string { + return string(t.raw) +} + +func (t *Token) Bytes() []byte { + return t.raw +} + +// HeaderPart returns token header part. +func (t *Token) HeaderPart() []byte { + return t.raw[:t.dot1] +} + +// ClaimsPart returns token claims part. +func (t *Token) ClaimsPart() []byte { + return t.raw[t.dot1+1 : t.dot2] +} + +// PayloadPart returns token payload part. +func (t *Token) PayloadPart() []byte { + return t.raw[:t.dot2] +} + +// SignaturePart returns token signature part. +func (t *Token) SignaturePart() []byte { + return t.raw[t.dot2+1:] +} + +// Claims returns token's claims. +func (t *Token) Claims() json.RawMessage { + return t.claims +} + +// DecodeClaims into a given parameter. +func (t *Token) DecodeClaims(dst any) error { + return json.Unmarshal(t.claims, dst) +} + +// Footer returns token's footer. +func (t *Token) Footer() json.RawMessage { + return t.footer +} + +// DecodeFooter into a given parameter. +func (t *Token) DecodeFooter(dst any) error { + return json.Unmarshal(t.footer, dst) +} + +// unexported method to check that token was created via Parse func. +func (t *Token) isValid() bool { + return t != nil && len(t.raw) > 0 +} + +type TokenType uint + +const ( + TokenUnknown TokenType = 0 + TokenV1Local TokenType = 1 + TokenV1Public TokenType = 2 + TokenV2Local TokenType = 3 + TokenV2Public TokenType = 4 + TokenV3Local TokenType = 5 + TokenV3Public TokenType = 6 + TokenV4Local TokenType = 7 + TokenV4Public TokenType = 8 +)