Skip to content

[BUG] All enforcers start using casbin_rule table from the latest adapter instance instead of the ones from their own adapters #26

@arafat-java

Description

@arafat-java

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"},
	})
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions