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
20 changes: 19 additions & 1 deletion cmd/cli/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,38 @@ package cli

import (
"fmt"
"errors"
"net/http"

"github.com/jean0t/cool-bank/internal/route"
"github.com/jean0t/cool-bank/internal/authentication"

"github.com/spf13/cobra"
)

var (
port string
router *http.ServeMux
publicKey, privateKey string
)

var serveCmd = &cobra.Command{
Use: "serve",
Aliases: []string{"s"},
Short: "Start the API",
PreRun: func (cmd *cobra.Command, args []string) {
router = route.CreateRouter()
// public_key.pem and private_key.pem must be provided
if publicKey == "" {
return errors.New("public_key.pem is mandatory. Use --public-key or -k to provide it.")
}
if privateKey == "" {
return errors.New("private_key.pem is mandatory. Use --private-key or -i to provide it.")
}

router = route.CreateRouter(publicKey, privateKey)
},
RunE: func(cmd *cobra.Command, args []string) error {

fmt.Println("[*] Server Started")
fmt.Printf("[*] Access the server with the url: http://localhost:%s/\n", port)
err = http.ListenAndServe(":"+port, router)
Expand All @@ -31,5 +43,11 @@ var serveCmd = &cobra.Command{

func init() {
serveCmd.Flags().StringVarP(&port, "port", "p", "9696", "Port that the server will use to listen to requests")
serveCmd.Flags().StringVarP(&publicKey, "public-key", "k", "", "Path to the public_key.pem file (mandatory)")
serveCmd.Flags().StringVarP(&privateKey, "private-key", "i", "", "Path to the private_key.pem file (mandatory)")

serveCmd.MarkFlagRequired("public-key")
serveCmd.MarkFlagRequired("private-key")

rootCmd.AddCommand(serveCmd)
}
8 changes: 4 additions & 4 deletions internal/authentication/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Claims struct {

//==========================================| Funtions

func CreateCookie(name, role string, expiration time.Duration, pathPrivateKey string) (string, error) {
func CreateJWT(name, role string, expiration time.Duration, pathPrivateKey string) (string, error) {
var (
err error
claims *Claims
Expand All @@ -42,7 +42,7 @@ func CreateCookie(name, role string, expiration time.Duration, pathPrivateKey st
},
}

privateKey, err = LoadPrivateKey(pathPrivateKey)
privateKey, err = loadPrivateKey(pathPrivateKey)
if err != nil {
return "", err
}
Expand All @@ -57,15 +57,15 @@ func CreateCookie(name, role string, expiration time.Duration, pathPrivateKey st
}


func VerifyCookie(tokenString, pathPublicKey string) bool {
func VerifyJWT(tokenString, pathPublicKey string) bool {
var (
err error
ok, isValid bool
publicKey *rsa.PublicKey
token *jwt.Token
)

publicKey, err = LoadPublicKey(pathPublicKey)
publicKey, err = loadPublicKey(pathPublicKey)
if err != nil {
fmt.Println("[!] Error loading RSA Public Key")
return false
Expand Down
52 changes: 52 additions & 0 deletions internal/authentication/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package authentication

import (
"strings"
"context"
"net/http"
"crypto/rsa"

"github.com/golang-jwt/jwt/v5"
)

func AuthMiddleware(publicKey *rsa.PublicKey) func(http.HandlerFunc) http.HandlerFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
authHeader, tokenString string
claims *Claims
ok bool
ctx context.Context
token *jwt.Token
err error

)

authHeader = r.Header.Get("Authorization")

if !strings.HasPrefix(authHeader, "Bearer ") {
http.Error(w, "Missing or invalid Authorization header", http.StatusUnauthorized)
return
}

tokenString = strings.TrimPrefix(authHeader, "Bearer ")
token, err = jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error){
return publicKey, nil
})

if err != nil || !token.Valid {
http.Error(w, "Invalid or expired token", http.StatusUnauthorized)
return
}

claims, ok = token.Claims.(*Claims)
if !ok {
http.Error(w, "Invalid token claims", http.StatusUnauthorized)
return
}

ctx = context.WithValue(r.Context(), "userClaims", claims)
next(w, r.WithContext(ctx))
}
}
}
4 changes: 2 additions & 2 deletions internal/authentication/rsa_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)


func LoadPrivateKey(path string) (*rsa.PrivateKey, error) {
func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
var (
err error
file *os.File
Expand Down Expand Up @@ -40,7 +40,7 @@ func LoadPrivateKey(path string) (*rsa.PrivateKey, error) {
}


func LoadPublicKey(path string) (*rsa.PublicKey, error) {
func loadPublicKey(path string) (*rsa.PublicKey, error) {
var (
err error
file *os.File
Expand Down
7 changes: 7 additions & 0 deletions internal/route/handler/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package handler

import (
"net/http"
)

func AccountHandler(w http.ResponseWriter, r *http.Request) {}
7 changes: 7 additions & 0 deletions internal/route/handler/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package handler

import (
"net/http"
)

func AdminHandler(w http.ResponseWriter, r *http.Request) {}
10 changes: 10 additions & 0 deletions internal/route/handler/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package handler

import (
"net/http"
)


func AuthenticationHandler(privateKeyPath string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {}
}
25 changes: 23 additions & 2 deletions internal/route/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import (
"net/http"
"fmt"

"github.com/jean0t/cool-bank/internal/authentication"
"github.com/jean0t/cool-bank/internal/route/handler"

Check failure on line 8 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

"github.com/jean0t/cool-bank/internal/route/handler" imported and not used
)


Expand Down Expand Up @@ -36,13 +39,31 @@
}


func CreateRouter() *http.ServeMux {
func CreateRouter(publicKeyPath, privateKeyPath string) *http.ServeMux {
var (
handler *Handler = registerHandlers()
router *http.ServeMux = http.NewServeMux()
)

router.HandleFunc("/", handler.GetHandler("/"))
// account routes
router.HandleFunc("/account", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/account/", http.StatusMovedPermanently)
})
router.Handle("/account/", authentication.AuthMiddleware(publicKey)(handler.AccountHandler))

Check failure on line 52 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

handler.AccountHandler undefined (type *Handler has no field or method AccountHandler)

Check failure on line 52 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

undefined: publicKey

// manager routes
router.HandleFunc("/admin", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/admin/", http.StatusMovedPermanently)
})
router.Handle("/admin/", authentication.AuthMiddleware(publicKey)(authentication.ManagerOnly(handler.AdminHandler)))

Check failure on line 58 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

handler.AdminHandler undefined (type *Handler has no field or method AdminHandler)

Check failure on line 58 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

undefined: authentication.ManagerOnly

Check failure on line 58 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

undefined: publicKey


// authentication routes
router.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/auth/", http.StatusMovedPermanently)
})
router.Handle("/auth/", handler.AuthenticationHandler(privateKeyPath))

Check failure on line 65 in internal/route/router.go

View workflow job for this annotation

GitHub Actions / build

handler.AuthenticationHandler undefined (type *Handler has no field or method AuthenticationHandler)


return router
}
28 changes: 28 additions & 0 deletions keys/private_key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC9LbacT8tQImwS
gJyqvteUVXqEKDdkh2ClJSh6Xf8M1gNtNXuLLwGQKIsbi+MKam6AgNrLzem3bl3c
uHNVA/zgahm2+B9DQoGivwzJ0yEYpXqiFcoAQXxsy4I2p8JvxDcFOMrfibUhnVB7
Xi+pJQjhPOH5Rfn5HNZOvQEI6eCnPYY6QOdbn1iR6dM1Z/rJn63hlxH1ACYOq5AK
HeAp0M8srZ2eICrktKlXMl61xVSJFdkZniKiAVNq+gZADWrlHX9I6IYhpKvq3aQY
LZP+UYxL9fAWTxPgSRr+6VHAVrsu4kG/MkmU9JyvkkmeG5YaNl4qAeT3QRKaak14
eEkhZmLtAgMBAAECggEAJP0hLWL0r9BrLRr0hvYVlK057Uknu4I0xVWEmphyXAIk
XWANreMc/SDQQiyR0eGJhZqsLRkvz2vG8ncmJcNH2GEmcf4FrtL8IeQVDgk3+Wex
mKuF+ZLUTzljVmhqvguxblXyZM66Gb52lAiQbRQOrmuHC4RBIhIfXPnbj/CaulgY
jEME9vz+frQqpvC2skco7JKELNGJYlq9vXmvIrvR04g4KTTUbfOSgxGVLkfpBL1P
npEmGzbBFEcNRmZLI7FOTXAcrBl0Q3rQHxLwdnblnTak5uIHfgn2sAOio+DJFckO
1+lkw2bgXy2VfhM57jeIiWg/vyoNrZJ1HKwIdACCwQKBgQD4YTarf8DFutvf68Fb
cd/qpvA5SaF+QnLZAgE5FCipsdnmJRmwHATiXnte6CuZ9BcPm9MIhhhrc2viuWze
koPRmiJxX4q4e4tiD8iZpcgR8Sd7dURwMtTvyzo8tMMrmC44S80/t8dS2oeFP4Ye
xm1jcLS4oM+44mxTkea3iOdoqQKBgQDC+4fpbcpn7trwY4PoXPI+TMNcOAWMgn/q
SpIcquoaYohdgK1YKoohD2h66US3QK5O0/a4h0uNZ8ozuBoGRQGa2TL1tTugd4fj
I4slOxoeQNRoIdeRVhSJ8E+nS4SZFj2sfjfVoA0MVp8ID+98z/rep91kcrIki1uz
MgXwXw8+pQKBgQDv2zEoPJ60U9axTsHSxQ0vVTb2m5xQiWrPFZiIvmbmONHr5jgA
UY6F7CfHZv10FruOXzRULuq2GSg+MkJoTaTubKKGSXV04hmgAQ3/EpE6gl9WYdBN
aUkoqGD87rLrDnLT+p+iwJ7D7DSjAM1MOuK3/McI5IK0UDO8IFFlO9f8wQKBgQCo
CV34LkZhi9fjk9/6QSAD0OQMdbtSfKUApYOGcUWPt5sN+fdqJD8mfsDsLFysEXIn
PUVDglX6Z5g7Ok4zWQUpDkZ8utPIVzsk5VzlmSnJKNXlaET/W9AXkKMU6mA8Do7Y
OW6lDGoyV/R2XkVmq1bozIJgLviXxgIhTNsRbNsWgQKBgQD2n/JmWy/dcSrL7Im+
3tPiCl6M8XG84M/ml3PFJBWw274e6kOsGYobgTEGkJwF45p7tppr9lPn9rFGoQnG
6MO339wy/ON2eYio0H7YkcvLJjkSx/v66yWJKa7nCiY8FubUoXjQ2mdo3PACR1Te
E41IiVKcOq6bbxcFpRNhk71OGw==
-----END PRIVATE KEY-----
9 changes: 9 additions & 0 deletions keys/public_key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvS22nE/LUCJsEoCcqr7X
lFV6hCg3ZIdgpSUoel3/DNYDbTV7iy8BkCiLG4vjCmpugIDay83pt25d3LhzVQP8
4GoZtvgfQ0KBor8MydMhGKV6ohXKAEF8bMuCNqfCb8Q3BTjK34m1IZ1Qe14vqSUI
4Tzh+UX5+RzWTr0BCOngpz2GOkDnW59YkenTNWf6yZ+t4ZcR9QAmDquQCh3gKdDP
LK2dniAq5LSpVzJetcVUiRXZGZ4iogFTavoGQA1q5R1/SOiGIaSr6t2kGC2T/lGM
S/XwFk8T4Eka/ulRwFa7LuJBvzJJlPScr5JJnhuWGjZeKgHk90ESmmpNeHhJIWZi
7QIDAQAB
-----END PUBLIC KEY-----
Loading