Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tn/swap mux for chi #843

Merged
merged 13 commits into from
Jun 14, 2023
4 changes: 2 additions & 2 deletions backend/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ The details for this service are detailed in [pipeline readme](/backend/pipeline

## Development Overview

This project utilizes Golang 1.13 (with modules), interfaces with a MySQL database and leverages Gorilla Mux to help with routing. The project is testable via docker/docker-compose and is also deployed via docker.
This project utilizes Golang 1.13 (with modules), interfaces with a MySQL database and leverages Chi to help with routing. The project is testable via docker/docker-compose and is also deployed via docker.
TylerNoblett marked this conversation as resolved.
Show resolved Hide resolved

### Development Environment

Expand Down Expand Up @@ -598,7 +598,7 @@ The project contains various source code directories, effectively acting as a co
├── server # Route endpoint definitions and basic request validation
│ ├── dissectors # A builder-pattern like solution for interpreting request objects
│ ├── middleware # Middleware to assist with request handling
│ ├── remux # A rewrapping package for better ergonmics when utilizing gorilla mux
│ ├── remux # A rewrapping package for better ergonmics when utilizing chi
│ ├── api.go # Routes for the "API" / screenshot tool
│ └── web.go # Routes for the web service
├── services # Underlying service logic. Also includes a number of unit tests
Expand Down
4 changes: 2 additions & 2 deletions backend/authschemes/auth_scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package authschemes

import (
"github.com/gorilla/mux"
"github.com/go-chi/chi/v5"
)

// AuthScheme provides a small interface into interacting with the AShirt backend authentication.
Expand All @@ -23,7 +23,7 @@ import (
// system can use to register custom endpoints. Each router is prefixed with /auth/{name} (as
// determined by the Name() method)
type AuthScheme interface {
BindRoutes(*mux.Router, AShirtAuthBridge)
BindRoutes(chi.Router, AShirtAuthBridge)
Name() string
FriendlyName() string
Flags() []string
Expand Down
27 changes: 14 additions & 13 deletions backend/authschemes/localauth/local_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import (
"fmt"
"net/http"

"github.com/gorilla/mux"
"github.com/go-chi/chi/v5"
"github.com/theparanoids/ashirt-server/backend"
"github.com/theparanoids/ashirt-server/backend/authschemes"
"github.com/theparanoids/ashirt-server/backend/authschemes/localauth/constants"
"github.com/theparanoids/ashirt-server/backend/dtos"
"github.com/theparanoids/ashirt-server/backend/server/dissectors"
"github.com/theparanoids/ashirt-server/backend/server/middleware"
"github.com/theparanoids/ashirt-server/backend/server/remux"
"golang.org/x/crypto/bcrypt"
Expand Down Expand Up @@ -77,13 +78,13 @@ func (LocalAuthScheme) Type() string {
//
// In each case above, the actual action is deferred to the bridge connecting this auth scheme to
// the underlying system/database
func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge) {
func (p LocalAuthScheme) BindRoutes(r chi.Router, bridge authschemes.AShirtAuthBridge) {
remux.Route(r, "POST", "/register", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
if !p.RegistrationEnabled {
return nil, fmt.Errorf("registration is closed to users")
}

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
TylerNoblett marked this conversation as resolved.
Show resolved Hide resolved
info := RegistrationInfo{
Username: dr.FromBody("username").Required().AsString(),
Email: dr.FromBody("email").Required().AsString(),
Expand Down Expand Up @@ -118,7 +119,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth
// convert authKey into readable format
readKey := base64.StdEncoding.EncodeToString(authKey)

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
info := RegistrationInfo{
Username: dr.FromBody("username").Required().AsString(),
Email: dr.FromBody("email").Required().AsString(),
Expand Down Expand Up @@ -147,7 +148,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth

remux.Route(r, "POST", "/login", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
username := dr.FromBody("username").Required().AsString()
password := dr.FromBody("password").Required().AsString()
if dr.Error != nil {
Expand All @@ -166,7 +167,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth

remux.Route(r, "POST", "/login/resetpassword", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
newPassword := dr.FromBody("newPassword").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand Down Expand Up @@ -194,7 +195,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth

remux.Route(r, "POST", "/login/totp", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
totpPasscode := dr.FromBody("totpPasscode").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand Down Expand Up @@ -229,7 +230,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth

remux.Route(r, "PUT", "/password", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
username := dr.FromBody("username").Required().AsString()
oldPassword := dr.FromBody("oldPassword").Required().AsString()
newPassword := dr.FromBody("newPassword").Required().AsString()
Expand All @@ -255,7 +256,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth
return nil, backend.UnauthorizedWriteErr(fmt.Errorf("Requesting user is not an admin"))
}

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
userSlug := dr.FromBody("userSlug").Required().AsString()
newPassword := dr.FromBody("newPassword").Required().AsString()

Expand Down Expand Up @@ -292,7 +293,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth
}))

remux.Route(r, "POST", "/link", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
username := dr.FromBody("username").Required().AsString()
password := dr.FromBody("password").Required().AsString()

Expand Down Expand Up @@ -324,7 +325,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth
}))

remux.Route(r, "GET", "/totp", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
userSlug := dr.FromBody("userSlug").AsString()
if dr.Error != nil {
return nil, dr.Error
Expand All @@ -342,7 +343,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth
}))

remux.Route(r, "POST", "/totp", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
secret := dr.FromBody("secret").Required().AsString()
passcode := dr.FromBody("passcode").Required().AsString()
if dr.Error != nil {
Expand Down Expand Up @@ -374,7 +375,7 @@ func (p LocalAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuth
}))

remux.Route(r, "DELETE", "/totp", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
userSlug := dr.FromBody("userSlug").AsString()
if dr.Error != nil {
return nil, dr.Error
Expand Down
4 changes: 2 additions & 2 deletions backend/authschemes/oidcauth/oidc_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"net/http"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/go-chi/chi/v5"
"github.com/gorilla/csrf"
"github.com/gorilla/mux"
"github.com/theparanoids/ashirt-server/backend"
"github.com/theparanoids/ashirt-server/backend/authschemes"
"github.com/theparanoids/ashirt-server/backend/config"
Expand Down Expand Up @@ -95,7 +95,7 @@ func (OIDCAuth) Flags() []string {
return []string{}
}

func (o OIDCAuth) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge) {
func (o OIDCAuth) BindRoutes(r chi.Router, bridge authschemes.AShirtAuthBridge) {
remux.Route(r, "GET", "/login", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
o.redirectLogin(w, r, bridge, modeLogin)
}))
Expand Down
13 changes: 7 additions & 6 deletions backend/authschemes/recoveryauth/recovery_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (
"strings"
"time"

"github.com/gorilla/mux"
"github.com/go-chi/chi/v5"
"github.com/theparanoids/ashirt-server/backend"
"github.com/theparanoids/ashirt-server/backend/authschemes"
"github.com/theparanoids/ashirt-server/backend/authschemes/recoveryauth/constants"
"github.com/theparanoids/ashirt-server/backend/logging"
"github.com/theparanoids/ashirt-server/backend/server/dissectors"
"github.com/theparanoids/ashirt-server/backend/server/middleware"
"github.com/theparanoids/ashirt-server/backend/server/remux"
)
Expand Down Expand Up @@ -45,9 +46,9 @@ func (RecoveryAuthScheme) Type() string {
return constants.Code
}

func (p RecoveryAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge) {
func (p RecoveryAuthScheme) BindRoutes(r chi.Router, bridge authschemes.AShirtAuthBridge) {
remux.Route(r, "POST", "/generate", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
userSlug := dr.FromBody("userSlug").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand All @@ -57,7 +58,7 @@ func (p RecoveryAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtA
}))

remux.Route(r, "POST", "/generateemail", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
userEmail := dr.FromBody("userEmail").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand All @@ -75,7 +76,7 @@ func (p RecoveryAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtA
return nil, backend.UnauthorizedWriteErr(fmt.Errorf("Requesting user is not an admin"))
}

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
firstName := dr.FromBody("firstName").Required().AsString()
lastName := dr.FromBody("lastName").AsString()
profile := authschemes.UserProfile{
Expand All @@ -97,7 +98,7 @@ func (p RecoveryAuthScheme) BindRoutes(r *mux.Router, bridge authschemes.AShirtA
}))

remux.Route(r, "GET", "/login", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
recoveryKey := dr.FromQuery("code").Required().AsString()

if dr.Error != nil {
Expand Down
15 changes: 8 additions & 7 deletions backend/authschemes/webauthn/webauthn.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import (
"net/url"
"strings"

"github.com/gorilla/mux"
"github.com/go-chi/chi/v5"
"github.com/theparanoids/ashirt-server/backend"
"github.com/theparanoids/ashirt-server/backend/authschemes"
"github.com/theparanoids/ashirt-server/backend/authschemes/webauthn/constants"
"github.com/theparanoids/ashirt-server/backend/config"
"github.com/theparanoids/ashirt-server/backend/helpers"
"github.com/theparanoids/ashirt-server/backend/server/dissectors"
"github.com/theparanoids/ashirt-server/backend/server/middleware"
"github.com/theparanoids/ashirt-server/backend/server/remux"

Expand Down Expand Up @@ -93,15 +94,15 @@ func (a WebAuthn) Type() string {
return constants.Name
}

func (a WebAuthn) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge) {
func (a WebAuthn) BindRoutes(r chi.Router, bridge authschemes.AShirtAuthBridge) {
remux.Route(r, "POST", "/register/begin", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
// validate basic registration data
if !a.RegistrationEnabled {
return nil, errors.New("registration is closed to users")
}

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
info := WebAuthnRegistrationInfo{
Email: dr.FromBody("email").Required().AsString(),
Username: dr.FromBody("username").Required().AsString(),
Expand Down Expand Up @@ -152,7 +153,7 @@ func (a WebAuthn) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge)

remux.Route(r, "POST", "/login/begin", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
username := dr.FromBody("username").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand Down Expand Up @@ -191,7 +192,7 @@ func (a WebAuthn) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge)
remux.JSONHandler(func(r *http.Request) (interface{}, error) {
callingUserId := middleware.UserID(r.Context())

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
info := WebAuthnRegistrationInfo{
Username: dr.FromBody("username").Required().AsString(),
CredentialName: dr.FromBody("credentialName").Required().AsString(),
Expand Down Expand Up @@ -229,7 +230,7 @@ func (a WebAuthn) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge)

remux.Route(r, "DELETE", "/credential/{credentialName}", remux.JSONHandler(func(r *http.Request) (interface{}, error) {
callingUserID := middleware.UserID(r.Context())
dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
credentialName := dr.FromURL("credentialName").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand All @@ -244,7 +245,7 @@ func (a WebAuthn) BindRoutes(r *mux.Router, bridge authschemes.AShirtAuthBridge)
return nil, backend.DatabaseErr(err)
}

dr := remux.DissectJSONRequest(r)
dr := dissectors.DissectJSONRequest(r)
credentialName := dr.FromBody("credentialName").Required().AsString()
if dr.Error != nil {
return nil, dr.Error
Expand Down
13 changes: 8 additions & 5 deletions backend/bin/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"net/http"

"github.com/go-chi/chi/v5"
"github.com/theparanoids/ashirt-server/backend"
"github.com/theparanoids/ashirt-server/backend/config"
"github.com/theparanoids/ashirt-server/backend/config/confighelpers"
Expand Down Expand Up @@ -41,13 +42,15 @@ func main() {
logging.Fatal(logger, "msg", "store setup error", "error", err)
}

mux := http.NewServeMux()
s := chi.NewRouter()

mux.Handle("/api/", server.API(
db, contentStore, logger,
))
s.Route("/api", func(r chi.Router) {
server.API(r,
db, contentStore, logger,
)
})

logger.Log("msg", "starting API server", "port", config.Port())
serveErr := http.ListenAndServe(":"+config.Port(), mux)
serveErr := http.ListenAndServe(":"+config.Port(), s)
logging.Fatal(logger, "msg", "server shutting down", "err", serveErr)
}
31 changes: 16 additions & 15 deletions backend/bin/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"
"time"

"github.com/go-chi/chi/v5"
"github.com/theparanoids/ashirt-server/backend"
"github.com/theparanoids/ashirt-server/backend/authschemes"
"github.com/theparanoids/ashirt-server/backend/authschemes/localauth"
Expand Down Expand Up @@ -117,22 +118,22 @@ func tryRunServer(logger logging.Logger) error {
logger.Log("msg", "No Emailer selected")
}

mux := http.NewServeMux()

mux.Handle("/web/", http.StripPrefix("/web", server.Web(
db, contentStore, &server.WebConfig{
CSRFAuthKey: []byte("DEVELOPMENT_CSRF_AUTH_KEY_SECRET"),
SessionStoreKey: []byte("DEVELOPMENT_SESSION_STORE_KEY_SECRET"),
UseSecureCookies: false,
AuthSchemes: schemes,
Logger: logger,
},
)))
mux.Handle("/api/", server.API(
jkennedyvz marked this conversation as resolved.
Show resolved Hide resolved
db, contentStore, logger,
))
r := chi.NewRouter()

r.Route("/web", func(r chi.Router) {
server.Web(r,
db, contentStore, &server.WebConfig{
CSRFAuthKey: []byte("DEVELOPMENT_CSRF_AUTH_KEY_SECRET"),
SessionStoreKey: []byte("DEVELOPMENT_SESSION_STORE_KEY_SECRET"),
UseSecureCookies: false,
AuthSchemes: schemes,
Logger: logger,
},
)
})

logger.Log("port", config.Port(), "msg", "Now Serving")
return http.ListenAndServe(":"+config.Port(), mux)
return http.ListenAndServe(":"+config.Port(), r)
}

func handleAuthType(cfg config.AuthInstanceConfig) (authschemes.AuthScheme, error) {
Expand Down