Skip to content
Open
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
16 changes: 10 additions & 6 deletions cmd/internal-api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/jwtauth/v5"
"github.com/go-playground/validator/v10"
"go.temporal.io/sdk/client"

"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
Expand Down Expand Up @@ -129,6 +130,9 @@ func main() {

defer temporalClient.Close()

// use a single instance of Validate, it caches struct info
validate := validator.New(validator.WithRequiredStructEnabled())

r.Route("/tenant", func(r chi.Router) {
if os.Getenv("ENABLE_JWT_AUTH") == "true" {
pubKey, _ := util.GetRawPublicKey()
Expand All @@ -143,12 +147,12 @@ func main() {
log.Fatalln("Enable jwt auth")
}

r.Post("/teams", handler.CreateTeam)
r.Post("/teams", handler.CreateTeam(validate))
r.Post("/teams/{team_id}/members/{member_id}", handler.AddMemberToTeam)
r.Post("/members", handler.CreateMember)
r.Post("/members", handler.CreateMember(validate))
})

temporalHandler := handler.NewTemporalHandler(temporalClient, *cfg)
onboardingHandler := handler.NewOnboardingHandler(temporalClient, *cfg, validate)

r.Route("/onboarding", func(r chi.Router) {
if os.Getenv("ENABLE_JWT_AUTH") == "true" {
Expand All @@ -164,8 +168,8 @@ func main() {
log.Fatalln("Enable jwt auth")
}

r.Post("/databases", temporalHandler.CreateTenantDB)
r.Post("/github-installation", temporalHandler.GithubInstallation)
r.Post("/databases", onboardingHandler.CreateTenantDB)
r.Post("/github-installation", onboardingHandler.GithubInstallation)
})

r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -176,7 +180,7 @@ func main() {
w.Write([]byte(`OK`))
})

r.Get("/users-count", temporalHandler.UsersCount)
r.Get("/users-count", onboardingHandler.UsersCount)

go func() {
log.Printf("Listening on %s\n", srv.Addr)
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.27.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/gofri/go-github-ratelimit/v2 v2.0.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand All @@ -40,6 +44,7 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
github.com/klauspost/compress v1.15.15 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.6 // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yi
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
Expand All @@ -43,10 +45,16 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
Expand Down Expand Up @@ -111,6 +119,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
Expand Down
84 changes: 45 additions & 39 deletions internal/internal-api/handler/create_member.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,68 @@ import (

api "github.com/dxta-dev/app/internal/internal-api"
"github.com/dxta-dev/app/internal/util"
"github.com/go-playground/validator/v10"
)

type CreateMemberRequestBody struct {
Name string `json:"name"`
Email *string `json:"email"`
Name string `json:"name" validate:"required"`
Email *string `json:"email" validate:"omitempty,email"`
}

type CreateMemberResponse struct {
MemberId int64 `json:"member_id"`
}

func CreateMember(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
func CreateMember(validate *validator.Validate) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

body := &CreateMemberRequestBody{}
body := &CreateMemberRequestBody{}

if err := json.NewDecoder(r.Body).Decode(body); err != nil {
fmt.Printf("Issue while parsing body. Error: %s", err.Error())
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
return
}
if err := json.NewDecoder(r.Body).Decode(body); err != nil {
fmt.Printf("Issue while parsing body. Error: %s", err.Error())
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
return
}

if body.Name == "" {
fmt.Println("No member name in request body")
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
}
err := validate.Struct(body)

authId := ctx.Value(util.AuthIdCtxKey).(string)
if err != nil {
fmt.Printf("Bad request body: %v", err.Error())
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
return
}

apiState, err := api.InternalApiState(authId, ctx)
authId := ctx.Value(util.AuthIdCtxKey).(string)

if err != nil {
util.JSONError(w, util.ErrorParam{Error: "Internal Server Error"}, http.StatusInternalServerError)
return
}
apiState, err := api.InternalApiState(authId, ctx)

newMemberRes, err := apiState.DB.CreateMember(body.Name, body.Email, ctx)
if err != nil {
util.JSONError(w, util.ErrorParam{Error: "Internal Server Error"}, http.StatusInternalServerError)
return
}

if err != nil {
util.JSONError(
w,
util.ErrorParam{Error: "Could not create new member"},
http.StatusInternalServerError,
)
return
}
newMemberRes, err := apiState.DB.CreateMember(body.Name, body.Email, ctx)

if err != nil {
util.JSONError(
w,
util.ErrorParam{Error: "Could not create new member"},
http.StatusInternalServerError,
)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(CreateMemberResponse{MemberId: newMemberRes.Id}); err != nil {
fmt.Printf("Issue while formatting response. Error: %s", err.Error())
util.JSONError(
w,
util.ErrorParam{Error: "Internal Server Error"},
http.StatusInternalServerError,
)
return
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(CreateMemberResponse{MemberId: newMemberRes.Id}); err != nil {
fmt.Printf("Issue while formatting response. Error: %s", err.Error())
util.JSONError(
w,
util.ErrorParam{Error: "Internal Server Error"},
http.StatusInternalServerError,
)
return
}
}
}
114 changes: 60 additions & 54 deletions internal/internal-api/handler/create_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,68 +7,74 @@ import (

api "github.com/dxta-dev/app/internal/internal-api"
"github.com/dxta-dev/app/internal/util"
"github.com/go-playground/validator/v10"
)

type CreateTeamRequestBody struct {
TeamName string `json:"teamName"`
TeamName string `json:"teamName" validate:"required"`
}

type CreateTeamResponse struct {
TeamId int64 `json:"team_id"`
}

func CreateTeam(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

body := &CreateTeamRequestBody{}

if err := json.NewDecoder(r.Body).Decode(body); err != nil {
fmt.Printf("Issue while parsing body. Error: %s", err.Error())
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
return
}

if body.TeamName == "" {
fmt.Printf("No team name provided. Team name: %s", body.TeamName)
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
}

authId := ctx.Value(util.AuthIdCtxKey).(string)

apiState, err := api.InternalApiState(authId, ctx)

if err != nil {
util.JSONError(w, util.ErrorParam{Error: "Internal Server Error"}, http.StatusInternalServerError)
return
}

organizationId, err := apiState.DB.GetOrganizationIdByAuthId(authId, ctx)

if err != nil {
util.JSONError(w, util.ErrorParam{Error: "Bad request"}, http.StatusBadRequest)
return
}

newTeamRes, err := apiState.DB.CreateTeam(body.TeamName, organizationId, ctx)

if err != nil {
util.JSONError(
w,
util.ErrorParam{Error: "Could not create new team"},
http.StatusInternalServerError,
)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(CreateTeamResponse{TeamId: newTeamRes.Id}); err != nil {
fmt.Printf("Issue while formatting response. Error: %s", err.Error())
util.JSONError(
w,
util.ErrorParam{Error: "Internal Server Error"},
http.StatusInternalServerError,
)
return
func CreateTeam(validate *validator.Validate) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

body := &CreateTeamRequestBody{}

if err := json.NewDecoder(r.Body).Decode(body); err != nil {
fmt.Printf("Issue while parsing body. Error: %s", err.Error())
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
return
}

err := validate.Struct(body)

if err != nil {
fmt.Printf("Bad request body: %v", err.Error())
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
return
}

authId := ctx.Value(util.AuthIdCtxKey).(string)

apiState, err := api.InternalApiState(authId, ctx)

if err != nil {
util.JSONError(w, util.ErrorParam{Error: "Internal Server Error"}, http.StatusInternalServerError)
return
}

organizationId, err := apiState.DB.GetOrganizationIdByAuthId(authId, ctx)

if err != nil {
util.JSONError(w, util.ErrorParam{Error: "Bad request"}, http.StatusBadRequest)
return
}

newTeamRes, err := apiState.DB.CreateTeam(body.TeamName, organizationId, ctx)

if err != nil {
util.JSONError(
w,
util.ErrorParam{Error: "Could not create new team"},
http.StatusInternalServerError,
)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(CreateTeamResponse{TeamId: newTeamRes.Id}); err != nil {
fmt.Printf("Issue while formatting response. Error: %s", err.Error())
util.JSONError(
w,
util.ErrorParam{Error: "Internal Server Error"},
http.StatusInternalServerError,
)
return
}
}
}
Loading
Loading