Skip to content

Commit

Permalink
Add #201 Read User, OrganisationType, Organisation from the applicati…
Browse files Browse the repository at this point in the history
…on configuration and create/update
  • Loading branch information
albinpa authored and georgepadayatti committed Oct 11, 2023
1 parent 63fe9e4 commit 141cc7c
Show file tree
Hide file tree
Showing 8 changed files with 579 additions and 33 deletions.
20 changes: 20 additions & 0 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ type WebhooksConfig struct {
KafkaConfig KafkaConfig
}

// Organization organization data type
type Organization struct {
Name string `valid:"required"`
Location string `valid:"required"`
Description string
EulaURL string
}

type OrgType struct {
Name string `valid:"required"`
}

type User struct {
Username string `valid:"required"`
Password string `valid:"required"`
}

// Configuration data type
type Configuration struct {
DataBase struct {
Expand All @@ -80,6 +97,9 @@ type Configuration struct {
Password string
}
ApplicationMode string
Organization Organization
Type OrgType
User User
Iam Iam
Twilio Twilio
Firebase Firebase
Expand Down
10 changes: 0 additions & 10 deletions src/handlerv1/organization_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,6 @@ func GetOrganizationByID(w http.ResponseWriter, r *http.Request) {
w.Write(response)
}

// GetOrganizationId Gets an organization Id.
func GetOrganizationId() (string, error) {
org, err := org.GetOrganization()
if err != nil {
log.Printf("Failed to get organization")
return "", err
}
return org.ID.Hex(), err
}

type orgUpdateReq struct {
Name string
Location string
Expand Down
37 changes: 17 additions & 20 deletions src/main/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"flag"
"fmt"
"log"
"net/http"
Expand All @@ -25,13 +24,6 @@ import (
"github.com/spf13/cobra"
)

func handleCommandLineArgs() (configFileName string) {
fconfigFileName := flag.String("config", "config-development.json", "configuration file")
flag.Parse()

return *fconfigFileName
}

func main() {

var rootCmd = &cobra.Command{Use: "bb-consent-api"}
Expand All @@ -45,47 +37,47 @@ func main() {
Run: func(cmd *cobra.Command, args []string) {

configFile := "/opt/bb-consent/api/config/" + configFileName
config, err := config.Load(configFile)
loadedConfig, err := config.Load(configFile)
if err != nil {
log.Printf("Failed to load config file %s \n", configFile)
panic(err)
}

log.Printf("config file: %s loaded\n", configFile)

err = database.Init(config)
err = database.Init(loadedConfig)
if err != nil {
panic(err)
}
log.Println("Data base session opened")

webhooks.Init(config)
webhooks.Init(loadedConfig)
log.Println("Webhooks configuration initialized")

err = kafkaUtils.Init(config)
err = kafkaUtils.Init(loadedConfig)
if err != nil {
panic(err)
}
log.Println("Kafka producer client initialised")

handler.IamInit(config)
handler.IamInit(loadedConfig)
log.Println("Iam initialized")

email.Init(config)
email.Init(loadedConfig)
log.Println("Email initialized")

token.Init(config)
token.Init(loadedConfig)
log.Println("Token initialized")

err = notifications.Init()
if err != nil {
panic(err)
}

firebaseUtils.Init(config)
firebaseUtils.Init(loadedConfig)
log.Println("Firebase initialized")

middleware.ApplicationModeInit(config)
middleware.ApplicationModeInit(loadedConfig)
log.Println("Application mode initialized")

// setup casbin auth rules
Expand All @@ -94,6 +86,11 @@ func main() {
panic(err)
}

// If the application starts in single tenant mode then create/update organisation, type, admin logic
if loadedConfig.ApplicationMode == config.SingleTenant {
SingleTenantConfiguration(loadedConfig)
}

router := mux.NewRouter()
httppathsv1.SetRoutes(router, authEnforcer)
httppathsv2.SetRoutes(router, authEnforcer)
Expand All @@ -114,20 +111,20 @@ func main() {

configFile := "/opt/bb-consent/api/config/" + configFileName

config, err := config.Load(configFile)
loadedConfig, err := config.Load(configFile)
if err != nil {
log.Printf("Failed to load config file %s \n", configFile)
panic(err)
}
log.Printf("config file: %s loaded\n", configFile)

err = database.Init(config)
err = database.Init(loadedConfig)
if err != nil {
panic(err)
}
log.Println("Data base session opened")

webhookdispatcher.WebhookDispatcherInit(config)
webhookdispatcher.WebhookDispatcherInit(loadedConfig)
},
}

Expand Down
134 changes: 134 additions & 0 deletions src/main/single_tenant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package main

import (
"log"

"github.com/bb-consent/api/src/common"
"github.com/bb-consent/api/src/config"
"github.com/bb-consent/api/src/org"
"github.com/bb-consent/api/src/orgtype"
"github.com/bb-consent/api/src/user"
"go.mongodb.org/mongo-driver/mongo"
)

func createOrganisationAdmin(config *config.Configuration) user.User {
u, err := user.GetByEmail(config.User.Username)
if err != nil {
log.Println("Failed to get user, creating new user.")
u, err = user.RegisterUser(config.User, config.Iam)
if err != nil {
log.Println("failed to create user")
panic(err)
}
}

return u
}

func createOrganisationType(config *config.Configuration) orgtype.OrgType {
orgType, err := orgtype.GetFirstType()
if err != nil {
if err == mongo.ErrNoDocuments {
log.Printf("Organization type doesn't exist, creating organization type.")
orgType, err = orgtype.AddOrganizationType(config.Type)
if err != nil {
log.Println("failed to add organization")
panic(err)
}
} else {
log.Println("failed to find organization")
panic(err)
}
}

return orgType
}

func addOrganisationAdminRole(organisationAdminId string, organisationId string) {
_, err := user.AddRole(organisationAdminId, user.Role{RoleID: common.GetRoleID("Admin"), OrgID: organisationId})
if err != nil {
log.Printf("Failed to update user : %v roles for org: %v", organisationAdminId, organisationId)
panic(err)
}
}

func createOrganisation(config *config.Configuration, orgType orgtype.OrgType, organisationAdminId string) org.Organization {
organization, err := org.GetFirstOrganization()
if err != nil {
if err == mongo.ErrNoDocuments {
log.Printf("Organization doesn't exist, creating organization.")
organization, err = org.AddOrganization(config.Organization, orgType.ID.Hex(), organisationAdminId)
if err != nil {
log.Println("failed to add organization")
panic(err)
}
// Add roles to organisation admin user
addOrganisationAdminRole(organisationAdminId, organization.ID.Hex())

} else {
log.Println("failed to find organization")
panic(err)
}
}

return organization
}

func deleteAllOrganisationTypes() {
typesCount, err := orgtype.GetTypesCount()
if err != nil {
log.Println("failed to count types")
panic(err)
}

if typesCount > 1 {
_, err := orgtype.DeleteAllTypes()
if err != nil {
log.Println("failed to delete organizations")
panic(err)
}
}
}

func deleteAllOrganisations() {
count, err := org.GetOrganizationsCount()
if err != nil {
log.Println("failed to count organization")
panic(err)
}
if count > 1 {
_, err := org.DeleteAllOrganizations()
if err != nil {
log.Println("failed to delete organizations")
panic(err)
}
}
}

// SingleTenantConfiguration If the application starts in single tenant mode then create/update organisation, type, admin logic
func SingleTenantConfiguration(config *config.Configuration) {

// Following is not allowed:
// 1. Updation of organisation is not allowed
// 2. Updation of organistaion type is not allowed
// 3. Updation of organisation admin is not allowed
// Note: Database has to be cleared if new organisation, type or admin has to be added

// If there is more than 1 organisation or type, delete all (this is a temporary and will be removed later)
deleteAllOrganisationTypes()
deleteAllOrganisations()

// Create an organisation admin
organisationAdmin := createOrganisationAdmin(config)
organisationAdminId := organisationAdmin.ID.Hex()

// TODO: If wrong password is provided, the application panics
user.GetOrganisationAdminToken(config.User, config.Iam)

// Create organisation type
orgType := createOrganisationType(config)

// Create organisation
createOrganisation(config, orgType, organisationAdminId)

}
7 changes: 6 additions & 1 deletion src/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/bb-consent/api/src/apikey"
handler "github.com/bb-consent/api/src/handlerv1"
"github.com/bb-consent/api/src/org"
"github.com/bb-consent/api/src/rbac"
"github.com/casbin/casbin/v2"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -204,9 +205,11 @@ func Authorize(e *casbin.Enforcer) Middleware {
}

var ApplicationMode string
var Organization config.Organization

func ApplicationModeInit(config *config.Configuration) {
ApplicationMode = config.ApplicationMode
Organization = config.Organization
}

// SetApplicationMode sets application modes for routes to either single tenant or multi tenant
Expand All @@ -218,12 +221,14 @@ func SetApplicationMode() Middleware {
return func(w http.ResponseWriter, r *http.Request) {

if ApplicationMode == config.SingleTenant {
organizationId, err := handler.GetOrganizationId()

organization, err := org.GetFirstOrganization()
if err != nil {
m := "failed to find organization"
common.HandleError(w, http.StatusBadRequest, m, err)
return
}
organizationId := organization.ID.Hex()
r.Header.Set(config.OrganizationId, organizationId)
}

Expand Down
Loading

0 comments on commit 141cc7c

Please sign in to comment.