Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Harald Wiesinger
    @s3ppo
    thanks i will try this :)
    is there a posibility with mongoRealmAuthenticator to set the default role to "user" ?
    i dont want to allow the users to set the role to admin :)
    Andrea Di Cesare
    @ujibang
    The correct way to force a default user role is to ovverride it with an interceptor. We plan for v5.3 to simplify this (check "simplified security" on https://restheart.org/docs/roadmap/)
    v5.2 will be released in December, v5.3 is planned for January/February..
    Ps (you can also set a writeFilter in the ACL, to avoid a user updating its role but still you need an interceptor for creation request since writeFilter works only on updates)
    Harald Wiesinger
    @s3ppo
    thanks a lot for your answer, i think i can wait for next year ;) meanwhile i will try to do solve it with the writefilter.. is it correct that i have to check the field _id in the users collection? best regards harald
    and then check the roles field if theres anything other the "user" ?
    Andrea Di Cesare
    @ujibang

    I suggest you this solution

    first, add a permission that only allows a user to GET and PATCH its own user document (I assume that the user document is created by a different process like https://github.com/SoftInstigate/restheart-examples/tree/master/user-signup)

    {
        "_id": { "$oid": "5d9485639eab3a852d48a1de" },
        "predicate": "path-template[value='/users/{username}'] and equals[%u, '${username}'] and (method[value='PATCH'] or method[value='GET'])",
        "roles": ["USER"],
        "priority": 1,
        "readFilter": null,
        "writeFilter": null
    }

    second, add the following interceptor that forbids PATCH requests containing the property roles

    @RegisterPlugin(name = "denyPatchRoles",
            description = "forbids PATCH request with roles property",
            interceptPoint = InterceptPoint.REQUST_AFTER_AUTH)
    public class DenyFilterOnUserPwd implements MongoInterceptor {
        @Override
        public boolean resolve(MongoRequest request, MongoResponse response) {
            return request.isPatch()
                    && request.getPath().startsWith("/users")
                    && hasRolesProperty(request.getContent());
        }
    
        @Override
        public void handle(MongoRequest request, MongoResponse response) throws Exception {
            response.setInError(HttpStatus.SC_FORBIDDEN, "You cannot update your roles");
        }
    
        private boolean hasRolesProperty(BsonDocument body) {
            return body != null && body.containsKey("roles");
        }
    }

    (I haven't tested the code, so it might need some tweaks)

    Harald Wiesinger
    @s3ppo
    thanks for the example.. i didnt use an interceptor yet, but i will try it in the next days :)
    Harald Wiesinger
    @s3ppo
    hi @ujibang i follwed your example with the single file mounting, and the application is now running after the docker update.. but when i try access one of my custom services i geht this error:
    14:43:13.740 [XNIO-1 task-2] ERROR org.restheart.handlers.ErrorHandler - Error handling the request. An external dependency is missing for service polygonsAll. Copy the missing dependency jar to the plugins directory to add it to the classpath
    is this by the last update or is this by the new mountings?
    Andrea Di Cesare
    @ujibang
    Hi @s3ppo , does your service polygonsAll use on one ore more dependencies? In case, you need to add them to the classpath. You can do it by simply adding the jars to the plugins directory. You can find an example at https://github.com/SoftInstigate/restheart-examples/blob/master/random-string-service
    It uses the maven-dependency-pluging to copy the jar of the external dependency to /target/lib
    Harald Wiesinger
    @s3ppo
    @ujibang i just updated the container as lot of times before :) there re no new dependencys i just added the custom plugins by file instead of the whole plugin path
    its the same jar file.. is there a possibilty to find find out which depency is missing ?
    Andrea Di Cesare
    @ujibang
    Can you paste the full exception?
    (ps make sure you compile your plugin with restheart-commons of the same version of restheart)
    Harald Wiesinger
    @s3ppo
    so, it is neccessary to compile my own plugins again with every new version of resthearth again ?
    11:52:44.520 [XNIO-1 task-3] DEBUG o.r.plugins.security.AuthMechanism - basicAuthMechanism -> NOT_ATTEMPTED
    11:52:44.803 [XNIO-1 task-3] ERROR org.restheart.handlers.ErrorHandler - Error handling the request. An external dependency is missing for service polygonsAll. Copy the missing dependency jar to the plugins directory to add it to the classpath
    
    java.lang.NoClassDefFoundError: com/mongodb/util/JSON
    at org.restheart.examples.PolygonsAllAvgService.handle(PolygonsAllAvgService.java:90)
    Caused by: java.lang.ClassNotFoundException: com.mongodb.util.JSON
    at java.base/java.net.URLClassLoader.findClass(Unknown Source)
    Andrea Di Cesare
    @ujibang
    Not necessary, but raccomanded (and first thing to do if you get an error)
    The latest updates the mongodb driver to latest version. And you see that a class that you were using is not there anymore
    Harald Wiesinger
    @s3ppo
    i am sorry ... i am not a java developer.. so this error is caused by a mongodb update or by a driver in the restheart docker?
    Andrea Di Cesare
    @ujibang
    By the updated mongodb driver boundled in in the updated RESTHeart.jar. I think you need just a small refactoring. The new v4.1 mongodb driver has a slightly different package structure than the 3.x
    driver
    Harald Wiesinger
    @s3ppo
    yeah it seems it isnt much.. the JSON.serialize istn working anymore because since driver 3.6 its deprecated
    but after some research i have no idea what i can do instead for this code line: response.setContent(JSON.serialize(listPoly).getBytes());
    Harald Wiesinger
    @s3ppo
    for me as java noob.. the method toString() on the BasicListDB sounds very similar, but when i try it i dont get any output
    response.setContent(listPoly.toString());
    also with the getBytes() method it has no return :(
    response.setContent(listPoly.toString().getBytes());
    Andrea Di Cesare
    @ujibang
    Which class is listPoly? And what RESTHeart Service implementation are you using?
    Harald Wiesinger
    @s3ppo
    listPoly is my Object of type BasicListDB
    my RESTHeart service is a ByteArrayService :)
    Harald Wiesinger
    @s3ppo
    is it possible that the read ACL filter is not working when using a aggregation query on it ?
    i set this acl on my friends collection:
    {
        "_id" : ObjectId("5fef54cd0f0126afdeaba6c5"),
        "predicate" : "path-prefix[/friends] and (method[GET] or method[PATCH] or method[POST])",
        "roles" : [ 
            "user"
        ],
        "priority" : 1,
        "readFilter" : {
            "_id" : {
                "_$eq" : "%USER"
            }
        },
        "writeFilter" : {
            "_id" : {
                "_$eq" : "%USER"
            }
        }
    }
    when i query it direct with /friends it is working
    but wen i query it with /friends/_aggrs/mylookup, then it shows also all other ids
    Harald Wiesinger
    @s3ppo
    i made now a workaround by bypassing the id as a avar.. then it is working correctly.. but for me it seems this is a bug
    https://..../friends/_aggrs/mylookup?avars={%22user%22:%22harald%22}
    Andrea Di Cesare
    @ujibang
    Hi Heral, the filter does not apply to aggregations.
    Andrea Di Cesare
    @ujibang

    We could automatically add a stage to the aggregation based on the readFilter, however this can potentially make the query too heavy in some cases. But I think that we could provide the readFilter in a predefined aggregation variable so it could be used as {"$var":"readFilter"}

    this can be then used in the aggregation definition, eg

    { "aggrs" : [
        { "stages" : [
            { "$match": {"$and": [{"status": "A" }, {"$var":"readFilter"}] }},
            { "$group" : { "_id" : "$gender",  "avg_age" : { "$avg" : "$age" } } },
            { "$merge": { "into": "avgAgeByGender" } }
            ],
                "type" : "pipeline",
                "uri" : "age-by-gender"
            }
        ]
    }

    what do you think?

    Harald Wiesinger
    @s3ppo
    yeah, that sounds good to me :)
    Andrea Di Cesare
    @ujibang

    ok, we'll do it. we are currently working on 6.0 to be release in few weeks.

    It will also allow you to write Service and Interceptors in javascript!!! (with hot deployment, no need to restart, just copy plugin.js in plugins directory). Here an example:

    const http = require('http');
    
    ({
        options: {
            name: "nodeModuleSrv",
            description: "just an example node service that requires http",
            uri: '/test',
            secured: false, // optional, default false
            matchPolicy: "PREFIX" // optional, default PREFIX
        },
    
        handle: (request, response) => new Promise((resolve, reject) => {
            // LOGGER.debug('request {}', request.getContent());
            const reqOpts = {
                hostname: 'httpbin.org',
                port: 80,
                path: '/anything',
                method: 'GET'
            }
    
            const req = http.request(reqOpts, res => {
                let data = '';
    
                res.on('data', d => {
                    data += d;
                });
    
                res.on('end', () => {
                    const rc = JSON.parse(request.getContent() || '{}');
    
                    let body = {
                        msg: `Hello ${rc.name || 'World'}`,
                        anything: JSON.parse(data)
                    };
    
                    response.setContent(JSON.stringify(body));
                    response.setContentTypeAsJson();
    
                    resolve();
                });
            })
    
            req.on("error", (err) => reject(err));
    
            req.end();
        })
    })
    Harald Wiesinger
    @s3ppo
    woah so nice :))) thats a game changer for me :) great job!
    cant wait to see and test it :)
    Harald Wiesinger
    @s3ppo
    i have one more question :)
    is there also a deleteFilter available for ACL securitys ?
    Damien
    @dev-indb
    @ujibang Service and Interceptors in JS look very powerful !
    Great job
    Andrea Di Cesare
    @ujibang
    @s3ppo there is no deleteFilter but writeFilter applies for DELETE requests as well
    Harald Wiesinger
    @s3ppo
    yeah, but then i have to make a second rule for DELETE only ;-)
    would be cool to have just one acl rule for 1 collection