Skip to content

Commit

Permalink
rsa jwt tokens and user groups (#7)
Browse files Browse the repository at this point in the history
* rsa decode and user groups

* delete old dir

* fix env
  • Loading branch information
kuderr authored Mar 8, 2023
1 parent 922f3cf commit e630eb5
Show file tree
Hide file tree
Showing 22 changed files with 570 additions and 349 deletions.
4 changes: 2 additions & 2 deletions .env.local
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
POSTGRES_URL="postgres://postgres/authdb"
SECRET="xxx"
POSTGRES_URL="postgres://postgres:postgres@postgres:55432/authdb"
JWT_PUBLIC_KEY="xxx"
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ COPY cmd ./cmd
COPY internal ./internal
COPY config ./config

RUN CGO_ENABLED=0 go build -o auther ./cmd/service/main.go
RUN CGO_ENABLED=0 go build -o checker ./cmd/service/main.go

FROM busybox
WORKDIR /bin
COPY --from=builder /opt/auther /bin/auther
COPY --from=builder /opt/checker /bin/checker
ENV GIN_MODE=release
CMD /bin/auther
CMD /bin/checker
22 changes: 13 additions & 9 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ tasks:
stop:
cmds:
- docker-compose --profile all rm -sf

start-dev:
cmds:
cmds:
- docker-compose --profile dev up --build
- defer: {task: stop}
- defer: { task: stop }

setup-test:
cmds:
cmds:
- docker-compose --profile test up --build -d

pretty:
cmds:
- go fmt ./...
- go mod tidy
- go clean

validate:
cmds:
cmds:
- golangci-lint run

test:
cmds:
- go test -v -coverprofile cover.out ./...
Expand All @@ -32,7 +32,11 @@ tasks:
build:
cmds:
- go build -race -o main.out cmd/service/main.go

run:
cmds:
- go run cmd/service/main.go
- go run cmd/service/main.go

sqlc-generate:
cmds:
- sqlc generate
28 changes: 14 additions & 14 deletions api/auther/main.go → api/checker/main.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package autherApi
package api

import (
"auther/internal/auther"
"auther/internal/tokens"
checker "checker/internal/core"
"checker/internal/tokens"
"net/http"

"github.com/gin-gonic/gin"
)

type AuthRequest struct {
Token string `json:"token,omitempty" binding:"required"`
auther.AccessData
checker.AccessData
}

type Service struct {
authInfo *auther.AuthInfo
secret string
authInfo *checker.AuthInfo
JWTPublicKey string
}

func NewService(authInfo *auther.AuthInfo, secret string) *Service {
return &Service{authInfo: authInfo, secret: secret}
func NewService(authInfo *checker.AuthInfo, JWTPublicKey string) *Service {
return &Service{authInfo: authInfo, JWTPublicKey: JWTPublicKey}
}

func (s *Service) RegisterHandlers(router *gin.Engine) {
Expand All @@ -35,22 +35,22 @@ func (s *Service) CheckAccess(c *gin.Context) {
return
}

token, err := tokens.DecodeToken(request.Token, s.secret)
token, err := tokens.DecodeToken(request.Token, s.JWTPublicKey)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

clientName, err := tokens.GetClientName(token)
clientID, err := tokens.GetClientID(token)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

hasAccess, err := s.authInfo.CheckAccess(&request.AccessData, clientName)
hasAccess, err := s.authInfo.CheckAccess(&request.AccessData, clientID)
if err != nil {
switch err.(type) {
case *auther.NotFoundError:
case *checker.NotFoundError:
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
default:
Expand All @@ -61,8 +61,8 @@ func (s *Service) CheckAccess(c *gin.Context) {

// Build response
if hasAccess {
c.IndentedJSON(http.StatusOK, gin.H{"message": "Access permit", "access": true, "client": clientName})
c.IndentedJSON(http.StatusOK, gin.H{"message": "Access permit", "access": true, "client": clientID})
} else {
c.IndentedJSON(http.StatusForbidden, gin.H{"message": "Access denied", "access": false, "client": clientName})
c.IndentedJSON(http.StatusForbidden, gin.H{"message": "Access denied", "access": false, "client": clientID})
}
}
34 changes: 24 additions & 10 deletions cmd/service/main.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package main

import (
autherApi "auther/api/auther"
"auther/config"
"auther/internal/auther"
"auther/internal/database"
api "checker/api/checker"
"checker/config"
checker "checker/internal/core"
"checker/internal/database"
"log"
"net/http"
"time"

"github.com/gin-gonic/gin"
Expand All @@ -26,28 +27,41 @@ func main() {
defer postgres.DB.Close()

queries := database.New(postgres.DB)
dbAuthStorage := auther.NewDatabaseAuthInfoStorage(queries)
builder := auther.NewBuilder(dbAuthStorage)
dbAuthStorage := checker.NewDatabaseAuthInfoStorage(queries)
builder := checker.NewBuilder(dbAuthStorage)
accesses, clients, err := builder.BuildAccessMap()
if err != nil {
log.Fatal(err.Error())
}

// For debugging access map
// accessMapJSON, _ := json.MarshalIndent(accesses, "", " ")
// log.Println(string(accessMapJSON))
// clientsJSON, _ := json.MarshalIndent(clients, "", " ")
// log.Println(string(clientsJSON))

// Instantiates the author service
authInfo := auther.NewAuthInfo(accesses, clients)
authService := autherApi.NewService(authInfo, cfg.Secret)
authInfo := checker.NewAuthInfo(accesses, clients)
authService := api.NewService(authInfo, cfg.JWTPublicKey)

// Register our service handlers to the router
router := gin.Default()
router.GET("/livez", healthCheck)
router.GET("/readyz", healthCheck)

authService.RegisterHandlers(router)

go syncAuthInfo(builder, authInfo)

// Start the server
router.Run()
router.Run(":5000")
}

func healthCheck(c *gin.Context) {
c.String(http.StatusOK, "OK")
}

func syncAuthInfo(builder *auther.Builder, authInfo *auther.AuthInfo) {
func syncAuthInfo(builder *checker.Builder, authInfo *checker.AuthInfo) {
ticker := time.NewTicker(60 * time.Second)
for {
select {
Expand Down
12 changes: 6 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

type Config struct {
Secret string `mapstructure:"SECRET"`
PostgresUrl string `mapstructure:"POSTGRES_URL"`
JWTPublicKey string `mapstructure:"JWT_PUBLIC_KEY"`
PostgresUrl string `mapstructure:"POSTGRES_URL"`
}

// TODO: create pydantic BaseSettings logic
Expand All @@ -28,9 +28,9 @@ func Read(tp, name, path string) (*Config, error) {
}
}

secret, ok := viper.Get("SECRET").(string)
JWTPublicKey, ok := viper.Get("JWT_PUBLIC_KEY").(string)
if !ok {
log.Fatalf("SECRET setting required")
log.Fatalf("JWT_PUBLIC_KEY setting required")
}

postgresUrl, ok := viper.Get("POSTGRES_URL").(string)
Expand All @@ -39,7 +39,7 @@ func Read(tp, name, path string) (*Config, error) {
}

return &Config{
Secret: secret,
PostgresUrl: postgresUrl,
JWTPublicKey: JWTPublicKey,
PostgresUrl: postgresUrl,
}, nil
}
5 changes: 2 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ version: "3.9"
services:
server:
profiles: [ 'all', 'dev' ]
image: auther:local
build:
context: .
environment:
POSTGRES_URL: postgres://postgres:postgres@postgres/authdb
SECRET: xxx
JWT_PUBLIC_KEY: xxx
ports:
- "8080:8080"
- "5000:5000"
depends_on:
- postgres

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module auther
module checker

go 1.19

Expand Down
Loading

0 comments on commit e630eb5

Please sign in to comment.