Git Product home page Git Product logo

casbin-server's People

Contributors

alikhanz avatar angry-chick avatar anton-khodak avatar bakhdaulet avatar betacat0 avatar chmorgan avatar dautushenka avatar guanz42 avatar hsluoyz avatar jalinwang avatar leonardo-ferreira avatar lnnt avatar ndodanli avatar nodece avatar outofeastgate avatar pokisemaine avatar prathik-kaliyambath avatar rico-ci avatar selflocking avatar shilps1583 avatar svetha-cvl avatar tangyang9464 avatar uran0sh avatar yyy1000 avatar zhenglin-li avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

casbin-server's Issues

Issues running in docker-compose

Hi All, I'm trying to run casbin-server in docker-compose along with a postgresql database based on the instructions here. I'm mounting a volume with the connection config json file and the model configuration files in the casbin-server container and setting up the environment variable ( to point to the config file. The casbin-server container logs says that it is Listening on 50051. I have mapped the local port 5005 to the port 50051 of the container. But I'm getting the error ERR_INVALID_HTTP_RESPONSE when trying to load the URL. I verified that I can connect to the database from the casbin-server container. I also tried running curl inside the casbin-server container on the port 50051, but I get a Connection reset by peer error.

What might be the issue here? Can you provide some guidance on the running casbin-server in docker compose?

I'm on a Macbook running macOS Ventura 13.1. Here is the docker-compose file I'm using:

services:
  auth-service:
    image: casbin/casbin-server:v1.9.0
    container_name: casbin-server
    ports:
      - 5005:50051
    volumes:
      - ./config:/config
      - ./data/model:/model
    environment:
      - DB_DRIVER=postgres
      - DB_HOST=db
      - DB_PORT=5432
      - DB_NAME=auth
      - DB_USERNAME=postgres
      - DB_PASSWORD=postgres
      - CONNECTION_CONFIG_PATH=/config/connection_config.json
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:12.2
    container_name: casbin_db
    ports:
      - 5432:5432
    restart: always
    volumes:
      - ./postgresql:/var/lib/postgresql
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-d", "auth", "-U", "postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=auth

The connection_config.json file is given below:

{
  "driver": "postgres",
  "connection": "host=db port=5432 user=postgres dbname=auth password=postgres",
  "enforcer": "/model/model.conf",
  "dbSpecified" : true
}

About HTTP interface

Some of my questions are:
1.How can I update the policy through the HTTP interface?
2.How to update model through HTTP interface?
3.Where is the API for verifying permissions(I mean HTTP interface)?
4.Do I need to implement it myself, or if there are detailed HTTP interface documents, can you provide them?

Environment variable for connection_config.json path

The path for config/connection_config.json is currently hardcoded in server/enforcer.go and server/adapter.go. Proposing an enhancement to read the connection_config.json location from an environment variable for ease of deployments. We can fall back to the existing config/connection_config.json path if no environment variable is set.

URL 404

The url here is 404; we should fix this as it is located on the main page and serves as an important guideline for our users.

image

image

How to run this docker image?

I downloaded the image you provided from the docker, but I don't know how to start it. Is it 'docker run -- name xxx - p 50051:50051 casbin/casbin-server'? Don't need to specify additional env variables?
Thanks.

CasBin server 1.02 can't be compiled for MSSQL

Hi,

I wanted to try casbin server with MSSQL, but I found out that the repo: github.com/jinzhu/gorm/dialects/mssql doesn't exist anymore.
So my question is: is or will MSSQL still be supported in casbin server?

TIA

Bert

GORM adapter is unable to read "PType" column

Issue:

  1. I have a database written by the casbin API (which uses the casbin-pg-adapter).
  2. The structure of the database looks like:

Screenshot 2022-08-15 at 04 39 06

3. The GORM adapter is able to read columns V0-5 but unable to read column ptype in the CasbinRule structure.
  1. As a result a panic is thrown

Request For Comments: Casbin-server V2 Api

I would like to propose the following gRPC proto definition to be implemented on what I believe to be the V2 of casbin-server

syntax = "proto3";

option java_multiple_files = true;
option java_package = "grpc.CasbinOrg.proto";
option java_outer_classname = "CasbinProto";
option go_package = "./;proto";
option csharp_namespace = "CasbinOrg.Grpc";

package casbin.rpc;

// How this works
// Upon installation, you would get a empty cluster with the root domain 
// representing the cluster itself. It would also contain a single user 
// and a single JWKS config pointing to a local, pre-installed key-pair 
// (which ideally you would change right away, but you can also "disable").
// The base domain would be backed by a local file adapter.
// First the casbin admin would register the adapters for the domains. Then
// he would register the JWKSs. Thirdly he would then register the domains,
// point out which domain is backed by which adapter, being the requests 
// validated against one or more key-pair
service ClusterManagementService{
    rpc GetAdapters (EmptyRequest) returns (stream AdapterDescription) {}
    rpc AddAdapter (AdapterDescription) returns (EmptyReply) {}
    rpc DeleteAdapter (AdapterDescription) returns (EmptyReply) {}
  
    rpc RegisterJWKS (JwksUri) returns (EmptyReply) {}
    rpc GetRegistredJWKSs (FilteredRequest) returns (GetRegistredJWKSsReply) {}
    rpc DeleteRegistredJWKS (JwksUri) returns (EmptyReply){}
  
    rpc RegisterDomain (DomainRegistry) returns (EmptyReply) {}
    rpc GetDomains (FilteredRequest) returns (stream DomainRegistry) {}
    rpc DeleteDomain (DomainRegistry) returns (EmptyReply) {}
}
// The main Casbin service definition.
// The client would instantiate this service, request a enforce compatible
// with its scope and then enforce away
service EnforcementService {
// Retrieves a enforcer based on the name of the domain provided. If security
// is up, the sub identified on the JWT would be enforced as:
// myMicroservice, domainNameInformedOnTheRequest, enforcers, read
// If security is turned off
  rpc GetEnforcer (GetEnforcerRequest) returns (GetEnforcerReply) {}

  //Unary request for enforcement
  rpc Enforce (EnforceRequest) returns (BoolReply) {}
  //Stream based, out of order request for enforcement. Designed for extremely
  //high-throughput scenarios
  rpc Enforce (stream StreamEnforceRequest) returns (stream StreamBoolReply) {}
}
service PolicesManagementService{
  rpc SavePolicy (EmptyRequest) returns (EmptyReply) {}

  //Removed "named" version of the api granting PolicyRequest a "name" field
  rpc AddPolicy (PolicyRequest) returns (BoolReply) {}
  rpc RemovePolicy (PolicyRequest) returns (BoolReply) {}
  rpc RemoveFilteredPolicy (FilteredPolicyRequest) returns (BoolReply) {}
  rpc GetPolicy (FilteredRequest) returns (Array2DReply) {}
  rpc GetFilteredPolicy (FilteredPolicyRequest) returns (Array2DReply) {}
  rpc AddGroupingPolicy (PolicyRequest) returns (BoolReply) {}
  rpc RemoveGroupingPolicy (PolicyRequest) returns (BoolReply) {}
  rpc RemoveFilteredGroupingPolicy (FilteredPolicyRequest) returns (BoolReply) {}
  rpc GetGroupingPolicy (FilteredRequest) returns (Array2DReply) {}
  rpc GetFilteredGroupingPolicy (FilteredPolicyRequest) returns (Array2DReply) {}
}
service UsersAndRolesManagementService{
  rpc GetAllSubjects (FilteredRequest) returns (ArrayReply) {}
  rpc GetAllObjects (FilteredRequest) returns (ArrayReply) {}
  rpc GetAllActions (FilteredRequest) returns (ArrayReply) {}
  rpc GetAllRoles (FilteredRequest) returns (ArrayReply) {}

  rpc HasPolicy (PolicyRequest) returns (BoolReply) {}
  rpc HasGroupingPolicy (PolicyRequest) returns (BoolReply) {}

  rpc GetRolesForUser (GetRolesForUserRequest) returns (ArrayReply) {}
  rpc GetUsersForRole (UserRoleRequest) returns (ArrayReply) {}
  rpc HasRoleForUser (UserRoleRequest) returns (BoolReply) {}
  rpc AddRoleForUser (UserRoleRequest) returns (BoolReply) {}
  rpc DeleteRoleForUser (UserRoleRequest) returns (BoolReply) {}
  rpc DeleteRolesForUser (UserRoleRequest) returns (BoolReply) {}
  rpc DeleteUser (UserRoleRequest) returns (BoolReply) {}
  rpc DeleteRole (UserRoleRequest) returns (EmptyReply) {}

  rpc GetPermissionsForUser (GetPermissionsForUserRequest) returns (Array2DReply) {}
  rpc DeletePermission (PermissionRequest) returns (BoolReply) {}
  rpc AddPermissionForUser (PermissionRequest) returns (BoolReply) {}
  rpc DeletePermissionForUser (PermissionRequest) returns (BoolReply) {}
  rpc DeletePermissionsForUser (PermissionRequest) returns (BoolReply) {}
  rpc HasPermissionForUser (PermissionRequest) returns (BoolReply) {}
}

message DomainRegistry{
    string name = 1;
    AdapterDescription adapter = 2;
    string owner = 3;
    repeated JwksUri jwks_settings = 4;
    int32 created_at = 5;
    int32 last_updated = 6;
    string created_by = 7;
    string last_updated_by = 8;
}

message GetRegistredJWKSsReply{
    repeated RegistredJWKS RegistredJWKSs = 1;
}

message RegistredJWKS{
    JwksUri uri = 1;
    repeated DomainRegistry usedBy = 2;
}

message JwksUri{
    string uri = 1;
}

message AdapterDescription{
    string realm = 1;
    string connectionString = 2;
    bool active = 3;
    int32 createdAt = 4;
    int32 lastUpdated = 5;
    string createdBy = 6;
    string lastUpdatedBy = 7;
}

message GetEnforcerRequest {
  string domainName = 1;
}

message EnforcerHandler {
  int32 handler = 1;
}

message NewAdapterRequest {
  string adapterName = 1;
  string driverName = 2;
  string connectString = 3;
  bool dbSpecified = 4;
}

message NewAdapterReply {
  int32 handler = 1;
}

message EnforceRequest {
  int32 enforcerHandler = 1;
  repeated string params = 2;
}

message StreamEnforceRequest {
    int32 operationId = 1;
    int32 enforcerHandler = 2;
    repeated string params = 3;
}

message StreamBoolReply {
    int32 operationId = 1;
    bool res = 2;
}

message BoolReply {
  bool res = 1;
}

message EmptyRequest {
  int32 handler = 1;
}

message EmptyReply {
}

message PolicyRequest {
  int32 enforcerHandler = 1;
  string pType = 2;
  string name = 3;
  repeated string params = 4;
}

message FilteredRequest {
  int32 enforcerHandler = 1;
  repeated string filters = 2;
  int32 skip = 3;
  int32 take = 4;
}

message ArrayReply {
  repeated string array = 1;
}

message FilteredPolicyRequest {
  int32 enforcerHandler = 1;
  string pType = 2;
  string name = 3;
  int32 fieldIndex = 4;
  repeated string fieldValues = 5;
}

message UserRoleRequest {
  int32 enforcerHandler = 1;
  string user = 2;
  string role = 3;
}

message GetRolesForUserRequest{
  int32 enforcerHandler = 1;
  string user = 2;
  bool implicit_roles_only = 3;
}

message PermissionRequest {
  int32 enforcerHandler = 1;
  string user = 2;
  repeated string permissions = 3;
}

message GetPermissionsForUserRequest {
    int32 enforcerHandler = 1;
    string user = 2;
    repeated string permissions = 3;
    bool implicit_permissions_only = 4;
  }

message Array2DReply {
  message d {
    repeated string d1 = 1;
  }

  repeated d d2 = 1;
}

Most important changes:

  • Operations are group by specific areas, which would simplify SDKs readability. E.G. casbin main object would be consistent of only 2 methods: getenforcer and enforce.
  • You won't be able to request new adapters or enforcers. You ask for enforcers only and the server will determine if you get a new one, or reuse a existing one.
  • operations like "AddNamedPolicy", "AddNamedGroupingPolicy" and "GetImplicitRolesForUser" were removed and the parameter for the "non-named/implicit" operations were increased by those fields

Environment Variables for DB creation

There should be a way to use environment variables for the config file used by the adapter creation of CaaS. Hence, I suggest that users can add environment variables to casbin-server/config/connection_config.json by using $ followed by the name of the respective variable. Furthermore, users should be allowed to define whether a database has been created (through the dbSpecified keyword).

This project is life ?

I'm creating the issue for extend the life cycle for this project.

  1. Has a team working ?
  2. Is safe implement the solution ?
  3. The GoLang and dependencies are constant updated?

Casbin-Server multi deployment

Quick scenario:
Imagine that I have a deployment of 2 Casbin-Servers behind a load balancer without sticky session. The client starts the flow by requesting a Adapter. This request gets balanced to server A. The next request, for an enforcer, will be balanced to server B, which will not have any idea about the Adapter and that will result in a error.

Correct?

Adapters should not be part of the API

Hello, it's more a question than an issue.

Can you please explain what the point of having the adapter in the client API?

I genuily expect from a casbin-server to have some kind of config file or command line parameters to start a server with a specific adapter, listening port, etc...
And the client should only know the server's uri.

If the client has to create the adapter, I don't see any reason to use the casbin-server over the classic casbin lib.

Am I missing something?

Lock enforcers

I've notices some strange behavior using ABAC. For example, I have a resource with two attributes "id" and "status". I print attrList in logs and when I see log like this "{verified 1 map[Id:V1 Status:V0]}" the result is right, but when it's "{verified 1 map[Status:V0, Id:V1 ]}" - the result is wrong. Mapping still seems correct, but the result is wrong
I create one adapter and one enforcer, that are saved in maps in server/enforcer.go, than I make several enforce requests with ABAC resource. Resource is parsed to attribute list and the enforcer model is also changes (e.x. resource attrList is like {1 verified} [Id:V0, Status:V1], model matcher changes to "m = g(r_sub, r_resource.V0) && r_resource.V1 != 'unverified' ") and due to golang random iteration attrList can be different each time. And the enforcer and its model are the shared resource between several enforce requests, so even though the resource mapping seems correct, the result is wrong sometimes because the model can be changed by another request before current request is done.

Probably enforcers must be locked, so different requests won't change it's model value concurrently

Casbin-server issues for enterprise deployments

The ideia of casbin is perfect, but for a enterprise scenario, casbin-server lacks a couple of features:

  1. Authenticated requests
    Casbin-server needs to have a self-contained authentication mech, or rely on a 3rd party to validate that the client is in-fact authorized to do so. This can be "basic" like a shared-secret between parties, but ideally, it has to be more robust (like a signed JWT token)
  2. Auditing
    Enterprises needs to be able to audit their application. Casbin-server can only become a (core) component of such an organization stack if it obliges to such scrutiny. There are two types of auditing workflows: mandatory and desired. They differ on a key aspect: On the mandatory setting, the response can only be provided AFTER the auditing log has been perpetuated (wether to a file, database, event hub or message queue)

Are there any plans on this area? if not can I draft some?

mutil application with casbin-server

if i have many application on the k8s
every application has their own casbin-server or all applications have only one common casbin-server ??

What does this mean: "Casbin-Server is designed to be compute-intensive (for calculating whether an access should be allowed) instead of a centralized policy storage."

I looked through the code and don't see any compute intensive operations designed to result in a computation expense for each policy access.

Also, isn't this a central policy storage as its a Casbin-server that could be used by a backend to enforce access policies? Or am I misunderstanding the project?

Backstory is that I'd like to add Casbin support to my backend restful api. I think I have a model I can understand and I'm able to insert that into my restful framework (go-swagger generated) but I'm looking at whether I should create another docker container just for Casbin and use casbin-server, and if I can then easily plug in the casbin/web-ui to this Casbin server to provide a way to debug policies. The backend will of course manage some of that itself, for example creating policies when users add new devices for example, but of course maintenance access is required to see what is going on there.

some grpc function return 2 values

error output:

rikenkiyoshis-MacBook-Pro:casbin-server bigticket$ go run main.go
# github.com/casbin/casbin-server/server
server/adapter.go:47:6: assignment mismatch: 1 variable but gormadapter.NewAdapter returns 2 values
server/enforcer.go:82:5: assignment mismatch: 1 variable but casbin.NewEnforcer returns 2 values
server/enforcer.go:82:26: undefined: casbin.NewModel
server/enforcer.go:84:5: assignment mismatch: 1 variable but casbin.NewEnforcer returns 2 values
server/enforcer.go:84:26: undefined: casbin.NewModel
server/enforcer.go:118:6: assignment mismatch: 1 variable but e.Enforce returns 2 values
server/management_api.go:204:44: multiple-value e.AddNamedPolicy() in single-value context
server/management_api.go:213:6: assignment mismatch: 1 variable but e.RemovePolicy returns 2 values
server/management_api.go:224:6: assignment mismatch: 1 variable but e.RemoveNamedPolicy returns 2 values
server/management_api.go:236:55: multiple-value e.RemoveFilteredNamedPolicy() in single-value context
server/management_api.go:236:55: too many errors

for example, casbin.proto.go file:

RemoveNamedPolicy(ctx context.Context, in *PolicyRequest, opts ...grpc.CallOption) (*BoolReply, error)

but in management_api.go file:

res := e.RemoveNamedPolicy(in.PType, in.Params)

it should be like this?

res,err := e.RemoveNamedPolicy(in.PType, in.Params)

Casbin-server doesn't use adapter settings from config file

Issue
If the client starts enforcer with an empty config adapter from config is not applied

Client code

cxt := context.Background()
c, err := client.NewClient(cxt, "127.0.0.1:50051", grpc.WithInsecure())
if err != nil {
	panic(err)
}
enforcer, err := c.NewEnforcer(cxt, client.Config{})

Concurrency issue in enforcer.go

  1. We are load testing the server using k6 tool and when i try to load the server with multiple users it crashes.
  2. The issue is that the maps used in enforcer.go (enforcerMap and adapterMap) need to be thread safe.
  3. Use either a sync map OR a RWMutex and protect the code where map is being written into.
  4. I was able to resolve it for myself using mutex, urge you to do the same.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.