casbin/mongodb-adapter

LoadPolicy not working with mongodb adapter

amiyamandal-dev opened this issue · 5 comments

hello,
working on a piece of code but seem like not working at all.

  1. haspolicy is always sending state of false if the policy is in the database
    for that, I have to make a query in DB to check that policy exist
  2. LoadPolicy is not working due to this when API is called API won't work
func updateGeneralPolicy(ce *casbin.Enforcer) {
	var policy [][]string
	policy = append(policy, []string{"", "/api/V1/register", "POST"})
	policy = append(policy, []string{"", "/api/V1/login", "POST"})
	policy = append(policy, []string{"", "/ping", "GET"})
	client, err := mongo.NewClient(options.Client().ApplyURI(model.MONGO_URI))
	if err != nil {
		log.Printf("somthing went wrong %s", err.Error())
	}
	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
	defer cancel()
	err = client.Connect(ctx)
	if err != nil {
		log.Printf("somthing went wrong %s", err.Error())
	}
	defer client.Disconnect(ctx)
	err = client.Ping(ctx, readpref.Primary())
	if err != nil {
		log.Printf("somthing went wrong %s", err.Error())
	}
	pol := client.Database("casbin_rule").Collection("casbin_rule")
	ctx, cancel = context.WithTimeout(ctx, 20*time.Second)
	defer cancel()
	for _, e := range policy {
		cursor, err := pol.Find(ctx, bson.M{"ptype": "p",
			"v0": "",
			"v1": e[1],
			"v2": e[2],
			"v3": "",
			"v4": "",
			"v5": ""})
		if err != nil {
			log.Fatal(err)
		}
		var prev []bson.M
		if err = cursor.All(ctx, &prev); err != nil {
			log.Fatal(err)
		}
		if len(prev) == 0 {
			ce.AddPolicy(e)

		}
	}
	ce.LoadPolicy()
}
func main() {
	a, err := mongodbadapter.NewAdapter(model.MONGO_URI)
	if err != nil {
		panic(err)
	}
	ce, err := casbin.NewEnforcer("rbac_model.conf", a)
	if err != nil {
		panic(err)
	}
	// Logging to a file.
	// f, _ := os.Create("gin.log")
	// gin.DefaultWriter = io.MultiWriter(f)
	updateGeneralPolicy(ce)
	r := gin.Default()
	r.Use(gin.Logger())
	r.Use(gin.Recovery())
	r.Use(authz.NewAuthorizer(ce))
	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})
	v1 := r.Group("api/V1")
	{
		v1.POST("/register", views.RegisterNewUser)
		v1.POST("/login", views.Login)
	}

	log.Print("server started")
	r.Run(":8080")
}

@nodece @GopherJ @dovics can anyone look into this issue?

Hi~ @amiyamandal-dev This is because the value of v0 is empty, the loadPolicy will return when find the first empty field.
https://github.com/casbin/mongodb-adapter/blob/master/adapter.go#L180

I am not quite sure what your first field is, you can delete it if it is not needed,But please don't leave it empty

hi @dovics and thanks for replying.

Since I want to create a general policy and some special policy.
For general policy.

ce.AddPolicy("", "/api/V1/register", "POST")

since API is self explanatory that anyone can register to it.
Thing is that when when no policy is their its working fine. AddPolicy able to insert in db and all the check is working fine.

if theirs is any way for making general policy

@amiyamandal-dev I guess you need this

ce.AddPolicy("*", "/api/V1/register", "POST")

and then use matching func in matcher

m = keyMatch2(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

if you need use the g() in matcher, you could run at first

ce.GetRoleManager().(*defaultrolemanager.RoleManager).AddMatchingFunc("KeyMatch2", util.KeyMatch2)

@dovics thanks it worked