Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting new_enforcer function #13

Open
SiddheshKanawade opened this issue Sep 4, 2022 · 5 comments
Open

Setting new_enforcer function #13

SiddheshKanawade opened this issue Sep 4, 2022 · 5 comments
Assignees
Labels
question Further information is requested

Comments

@SiddheshKanawade
Copy link
Member

I am trying to draft the new_enforcer, which is as below:

 async fn new_enforcer(
        &self,
        i: Request<casbin_proto::NewEnforcerRequest>,
    ) -> Result<Response<casbin_proto::NewEnforcerReply>, Status> {
        let mut a: Option<Box<dyn Adapter>> = None;
        let e: CachedEnforcer;

        let get_inner = i.into_inner();

        if get_inner.adapter_handle != -1 {
            a = match self.get_adapter(get_inner.adapter_handle).await {
                Ok(&v) => Some(v),
                Err(_) => return Ok(Response::new(casbin_proto::NewEnforcerReply { handler: 0 })),
            };
        }

        if get_inner.model_text == String::from("") {
            let cfg = adapter::load_configuration("config/connection_config.json").await?;
            let data = match std::fs::read_to_string(cfg.enforcer.as_str()) {
                Ok(v) => v,
                Err(_) => return Ok(Response::new(casbin_proto::NewEnforcerReply { handler: 0 })),
            };
        }

        if a.is_none() {
            let m = match DefaultModel::from_str(get_inner.model_text.as_str()).await {
                Ok(v) => v,
                Err(_) => return Ok(Response::new(casbin_proto::NewEnforcerReply { handler: 0 })),
            };
            e = match casbin::CachedEnforcer::new(m, ()).await {
                Ok(v) => v,
                Err(_) => return Ok(Response::new(casbin_proto::NewEnforcerReply { handler: 0 })),
            };
        } else {
            let m = match DefaultModel::from_str(get_inner.model_text.as_str()).await {
                Ok(v) => v,
                Err(_) => return Ok(Response::new(casbin_proto::NewEnforcerReply { handler: 0 })),
            };

            e = match casbin::CachedEnforcer::new(m, a).await {
                Ok(v) => v,
                Err(er) => return Ok(Response::new(casbin_proto::NewEnforcerReply { handler: 0 })),
            };
        }

        let epass = Arc::new(Mutex::new(e));
        let h = self.add_enforcer(epass);
        Ok(Response::new(casbin_proto::NewEnforcerReply { handler: h }))
    }

Here I am getting error in self.get_adapter() and self.add_enforcer()function, the error message is as follows:

error[E0507]: cannot move out of a shared reference
   --> src/server/rpc_calls.rs:355:23
    |
355 |             a = match self.get_adapter(get_inner.adapter_handle).await {
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
356 |                 Ok(&v) => Some(v),
    |                     -
    |                     |
    |                     data moved here
    |                     move occurs because `v` has type `Box<dyn Adapter>`, which does not implement the `Copy` trait
error[E0596]: cannot borrow `*__self` as mutable, as it is behind a `&` reference
   --> src/server/rpc_calls.rs:391:17
    |
346 |         &self,
    |          ---- help: consider changing this to be a mutable reference: `&mut CasbinGRPC`
...
391 |         let h = self.add_enforcer(epass);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^ `__self` is a `&` reference, so the data it refers to cannot be borrowed as mutable

After the initial research I was able to figure out that this is due to the & reference from the get_adapter function, which is as below:

pub async fn get_adapter(&self, handle: i32) -> Result<&Box<dyn Adapter>, &str> {
        self.adapter_map.get(&handle).ok_or("No adapter found")
    }

Here, adapter_map is a hashmap:

pub struct CasbinGRPC {
    enforcer_map: HashMap<i32, Arc<Mutex<CachedEnforcer>>>,
    adapter_map: HashMap<i32, Box<dyn Adapter>>,
}

When we take any value from the hashmap, we get the reference of that value rather than the copy of the value. In short, when we do self.adapter_map.get(&handle), we get &Box<dyn Adapter> and not Box<dyn Adapter>. Since Copy trait is not implemented for Adapter in the casbin-rs, we can't use methods like to_owned to drop the &.
I tried to send the Box<dyn Adapter> wrapped in Arc<Mutex<Box<dyn Adapter>>> but then in convert.rs of casbin-rs we can't call TryIntoAdapter for it.

I am unable to figure out how can I resolve the above errors.

@SiddheshKanawade
Copy link
Member Author

@hsluoyz @hackerchai @PsiACE please help

@SiddheshKanawade
Copy link
Member Author

SiddheshKanawade commented Sep 4, 2022

I tried to send the adapter as wrapped under RefCell but since its not thread safe, I am unable to use it.
The major cause of error is due to &Box<dyn Adapter> instead of Box<dyn Adapter> on calling by key from hashmap. As of now, I am able to thing of the following possible approaches:

  1. Make another datastructure similar to hashmap which will return required Box<dyn Adapter>
  2. Make some changes in casbin-rs as that it can implement TryIntoAdapter for Arc<Mutex<T>>.

In this first approach, I think we will loose the optimisation and hence was planning to go with the second one. @hsluoyz @hackerchai is it fine if I make some changes in casbin-rs?

Until then I will try to close the other issues in sqlx-adapter and casbin-actix-auth

Update: sqlx adapter issue has been resolved

@SiddheshKanawade
Copy link
Member Author

@hackerchai @hsluoyz can you please comment on above issue and give your views. I have tried every possible thing I could think of, adapter doesn’t have clone or copy traits implemented, hence can’t directly copy it without taking reference.

@hsluoyz hsluoyz self-assigned this Sep 8, 2022
@hsluoyz hsluoyz added the question Further information is requested label Sep 8, 2022
@hsluoyz
Copy link
Member

hsluoyz commented Sep 8, 2022

@SiddheshKanawade plz contact @hackerchai

@SiddheshKanawade
Copy link
Member Author

@SiddheshKanawade plz contact @hackerchai

Will dm him too, it seems he isn’t active over here recently. Till then I am working on diesel adapter #66

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants