Skip to content

Commit

Permalink
fix: thirdparty and multitenancy
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc committed Jul 26, 2024
1 parent ed69b82 commit c0622ec
Show file tree
Hide file tree
Showing 4 changed files with 394 additions and 2 deletions.
2 changes: 2 additions & 0 deletions test/test-server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ require (
require (
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/derekstavis/go-qs v0.0.0-20180720192143-9eef69e6c4e7 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
golang.org/x/crypto v0.2.0 // indirect
golang.org/x/net v0.2.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
Expand Down
43 changes: 41 additions & 2 deletions test/test-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
"github.com/supertokens/supertokens-golang/recipe/session"
"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
"github.com/supertokens/supertokens-golang/recipe/thirdparty"
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)

Expand Down Expand Up @@ -51,10 +53,10 @@ func main() {
addSessionRoutes(router)
// addAccountLinkingRoutes(router)
// addEmailVerificationRoutes(router)
// addMultitenancyRoutes(router)
addMultitenancyRoutes(router)
// addPasswordlessRoutes(router)
// addMultiFactorAuthRoutes(router)
// addThirdPartyRoutes(router)
addThirdPartyRoutes(router)
// addTOTPRoutes(router)
// addUserMetadataRoutes(router)

Expand Down Expand Up @@ -306,6 +308,43 @@ func recipeListFromRecipeConfigs(recipeListMaps []interface{}) []supertokens.Rec
}

recipeList = append(recipeList, emailverification.Init(recipeConfig))
} else if recipeItemMap["recipeId"] == "thirdparty" {
var recipeConfigMap map[string]interface{}
err := json.Unmarshal([]byte(recipeItemMap["config"].(string)), &recipeConfigMap)
if err != nil {
log.Printf("Error unmarshaling recipe config: %v", err)
continue
}
recipeConfig := tpmodels.TypeInput{}

if signInAndUpFeature, ok := recipeConfigMap["signInAndUpFeature"].(map[string]interface{}); ok {
if providers, ok := signInAndUpFeature["providers"].([]interface{}); ok {
for _, provider := range providers {
providerInput := tpmodels.ProviderInput{}
providerMap := provider.(map[string]interface{})

if config, ok := providerMap["config"].(map[string]interface{}); ok {
configBytes, err := json.Marshal(config)
if err != nil {
log.Printf("Error marshaling provider config: %v", err)
continue
}
err = json.Unmarshal(configBytes, &providerInput.Config)
if err != nil {
log.Printf("Error unmarshaling provider config: %v", err)
continue
}
}

if includeInNonPublicTenantsByDefault, ok := providerMap["includeInNonPublicTenantsByDefault"].(bool); ok {
providerInput.IncludeInNonPublicTenantsByDefault = &includeInNonPublicTenantsByDefault
}
recipeConfig.SignInAndUpFeature.Providers = append(recipeConfig.SignInAndUpFeature.Providers, providerInput)
}
}
}

recipeList = append(recipeList, thirdparty.Init(&recipeConfig))
}
}
return recipeList
Expand Down
220 changes: 220 additions & 0 deletions test/test-server/multitenancy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package main

import (
"encoding/json"
"net/http"

"github.com/gorilla/mux"
"github.com/supertokens/supertokens-golang/recipe/multitenancy"
"github.com/supertokens/supertokens-golang/recipe/multitenancy/multitenancymodels"
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)

func addMultitenancyRoutes(router *mux.Router) {
router.HandleFunc("/test/multitenancy/createorupdatetenant", createOrUpdateTenantHandler).Methods("POST")
router.HandleFunc("/test/multitenancy/deletetenant", deleteTenantHandler).Methods("POST")
router.HandleFunc("/test/multitenancy/gettenant", getTenantHandler).Methods("POST")
router.HandleFunc("/test/multitenancy/listalltenants", listAllTenantsHandler).Methods("GET")
router.HandleFunc("/test/multitenancy/createorupdatethirdpartyconfig", createOrUpdateThirdPartyConfigHandler).Methods("POST")
router.HandleFunc("/test/multitenancy/deletethirdpartyconfig", deleteThirdPartyConfigHandler).Methods("POST")
router.HandleFunc("/test/multitenancy/associateusertotenant", associateUserToTenantHandler).Methods("POST")
router.HandleFunc("/test/multitenancy/disassociateuserfromtenant", disassociateUserFromTenantHandler).Methods("POST")
}

func createOrUpdateTenantHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
Config multitenancymodels.TenantConfig `json:"config"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.CreateOrUpdateTenant(body.TenantId, body.Config, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}

func deleteTenantHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.DeleteTenant(body.TenantId, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}

func getTenantHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

tenant, err := multitenancy.GetTenant(body.TenantId, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(tenant)
}

func listAllTenantsHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.ListAllTenants(userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}

func createOrUpdateThirdPartyConfigHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
Config tpmodels.ProviderConfig `json:"config"`
SkipValidation *bool `json:"skipValidation"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.CreateOrUpdateThirdPartyConfig(body.TenantId, body.Config, body.SkipValidation, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}

func deleteThirdPartyConfigHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
ThirdPartyId string `json:"thirdPartyId"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.DeleteThirdPartyConfig(body.TenantId, body.ThirdPartyId, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}

func associateUserToTenantHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
UserId string `json:"userId"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.AssociateUserToTenant(body.TenantId, body.UserId, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}

func disassociateUserFromTenantHandler(w http.ResponseWriter, r *http.Request) {
var body struct {
TenantId string `json:"tenantId"`
UserId string `json:"userId"`
UserContext map[string]interface{} `json:"userContext"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

var userContext supertokens.UserContext = nil
if body.UserContext != nil {
userContext = &body.UserContext
}

response, err := multitenancy.DisassociateUserFromTenant(body.TenantId, body.UserId, userContext)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

json.NewEncoder(w).Encode(response)
}
Loading

0 comments on commit c0622ec

Please sign in to comment.