-
Notifications
You must be signed in to change notification settings - Fork 29
Description
We are using casbin / casbin-pg-adapter in a multi tenant system
So I am creating a seperate adapter for each tenant with table name of the format casbin_rule_ and then caching then so that next time onwards I use the same adpater for the tenant and dont have to create that again and again.
However what I noticed is that it is not taking the table name from the adapter but somehow the table name of the last adapter that gets initialized.
And this is a serious problem for us because then the tenant data gets mixed.
Following is the code
In the GetObjectPermissions() I first create adapter for T1 and then load permissions. It works fine and uses table casbin_rule_T1
Next create adapter for T2 and then load permissions. It works fine as well and uses table casbin_rule_T2.
But now when I use adapter of T1 it accesses table and uses table casbin_rule_T2 and not and uses table casbin_rule_T1
Similarly when I later create adapter for T3 and then load permissions, it works fine and uses table casbin_rule_T3
But now both the previous adpaters for T1 and T2 also start using table casbin_rule_T3, instead if casbin_rule_T1 and casbin_rule_T2 respectively
package check
import (
"context"
"fmt"
"gopkgs.sas.com/zlog"
"mkt-infra-iam/config"
pgAdapter "github.com/casbin/casbin-pg-adapter"
"github.com/casbin/casbin/v2"
"github.com/go-pg/pg/v9"
_ "github.com/go-sql-driver/mysql"
)
var logger *zlog.Logger = zlog.L()
var dbAdapters = make(map[string]*pgAdapter.Adapter)
//Logging DB queries
type dbLogger struct{}
func (d dbLogger) BeforeQuery(ctx context.Context, q *pg.QueryEvent) (context.Context, error) {
query, _ := q.FormattedQuery()
logger.Debug(query)
return ctx, nil
}
func (d dbLogger) AfterQuery(ctx context.Context, q *pg.QueryEvent) error {
return nil
}
func getAdapter(tenantMoniker string) *pgAdapter.Adapter {
tenantAdapter := dbAdapters[tenantMoniker]
if tenantAdapter == nil {
opts, _ := pg.ParseURL("postgresql://admin:xyx@" + "localhost:5432")
db := pg.Connect(opts)
db.AddQueryHook(dbLogger{})
tableName := "casbin_rule_" + tenantMoniker
tenantAdapter, _ := pgAdapter.NewAdapterByDB(db, pgAdapter.WithTableName(tableName))
dbAdapters[tenantMoniker] = tenantAdapter
logger.Info("Returning new adapter for tenant '" + tenantMoniker + "' . DB :- " + config.PostGresURL + " - " + fmt.Sprintf("%#v", tenantAdapter))
return tenantAdapter
} else {
logger.Info("Returning existing adapter for tenant '" + tenantMoniker + "' . DB :- " + config.PostGresURL + " - " + fmt.Sprintf("%#v", tenantAdapter))
return tenantAdapter
}
}
func getNewEnforcer(tenantMoniker string) *casbin.Enforcer {
e, _ := casbin.NewEnforcer("model.conf")
e.SetAdapter(getAdapter(tenantMoniker))
return e
}
func GetObjectPermissions() {
e := getNewEnforcer("T1")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
e = getNewEnforcer("T2")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
e = getNewEnforcer("T1")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
e = getNewEnforcer("T3")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
e = getNewEnforcer("T1")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
e = getNewEnforcer("T2")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
e = getNewEnforcer("T3")
e.LoadFilteredPolicy(&pgAdapter.Filter{
P: []string{"", "objectId", "", "objectType"},
})
}