Example #1
0
List *permission_list_load(json_t *json) {
    if (!json_is_array(json) || json_array_size(json) == 0) {
        return NULL;
    }
    List *rslt = dslink_calloc(1, sizeof(List));
    list_init(rslt);

    size_t idx;
    json_t *value;
    json_array_foreach(json, idx, value) {
        if (json_array_size(value) == 2) {
            json_t *v0 = json_array_get(value, 0);
            json_t *v1 = json_array_get(value, 1);
            if (json_is_string(v0) && json_is_string(v1)) {
                const char* vc0 = json_string_value(v0);
                const char* vc1 = json_string_value(v1);
                PermissionLevel p = permission_str_level(vc1);
                if (p <= PERMISSION_CONFIG) {
                    PermissionPair * pair = dslink_malloc(sizeof(PermissionPair));
                    pair->group = dslink_strdup(vc0);
                    pair->permission = p;
                    dslink_list_insert(rslt, pair);
                }
            }
        }
    }
    return rslt;
}
Example #2
0
int broker_msg_handle_subscribe(RemoteDSLink *link, json_t *req) {
    broker_utils_send_closed_resp(link, req, NULL);

    json_t *paths = json_object_get(req, "paths");
    if (!json_is_array(paths)) {
        return 1;
    }


    json_t *maxPermitJson = json_object_get(req, "permit");
    PermissionLevel maxPermit = PERMISSION_CONFIG;
    if (json_is_string(maxPermitJson)) {
        maxPermit = permission_str_level(json_string_value(maxPermitJson));
    }

    if (maxPermit < PERMISSION_READ) {
        return 0;
    }

    size_t index;
    json_t *obj;
    json_array_foreach(paths, index, obj) {
        handle_subscribe(link, obj);
    }
Example #3
0
int broker_msg_handle_invoke(RemoteDSLink *link, json_t *req) {
    json_t *reqRid = json_object_get(req, "rid");
    json_t *reqPath = json_object_get(req, "path");
    if (!(reqRid && reqPath)) {
        return 1;
    }
    json_t *maxPermitJson = json_object_get(req, "permit");
    PermissionLevel maxPermit = PERMISSION_CONFIG;
    if (json_is_string(maxPermitJson)) {
        maxPermit = permission_str_level(json_string_value(maxPermitJson));
    }

    const char *path = json_string_value(reqPath);
    char *out = NULL;
    BrokerNode *node = broker_node_get(link->broker->root, path, &out);
    if (!node) {
        broker_utils_send_closed_resp(link, req, "disconnected");
        return 0;
    }

    Broker *broker = mainLoop->data;

    PermissionLevel permissionOnPath = get_permission(path, broker->root, link);
    if (permissionOnPath > maxPermit) {
        permissionOnPath = maxPermit;
    }

    if (permissionOnPath == PERMISSION_NONE) {
        broker_utils_send_closed_resp(link, req, "permissionDenied");
        return 0;
    }
    if (node->type == REGULAR_NODE) {
        json_t *invokableJson = json_object_get(node->meta, "$invokable");

        PermissionLevel level = permission_str_level(json_string_value(invokableJson));
        if (level > permissionOnPath) {
            broker_utils_send_closed_resp(link, req, "permissionDenied");
        } else if (node->on_invoke) {
            node->on_invoke(link, node, req, maxPermit);
        }
        return 0;
    } else if (node->type != DOWNSTREAM_NODE) {
        // Unknown node type
        broker_utils_send_closed_resp(link, req, "disconnected");
        return 0;
    }

    DownstreamNode *ds = (DownstreamNode *) node;
    uint32_t rid = broker_node_incr_rid(ds);

    if (!ds->link) {
        broker_utils_send_closed_resp(link, req, "disconnected");
        return 0;
    }

    BrokerInvokeStream *s = broker_stream_invoke_init();

    s->responder_rid = rid;
    s->responder = ds->link;
    s->resp_close_cb = remote_invoke_resp_disconnected;

    s->requester_rid = (uint32_t) json_integer_value(reqRid);
    s->requester = link;
    s->req_close_cb = remote_invoke_req_closed;

    ref_t *refStream = dslink_ref(s, NULL);
    dslink_map_set(&ds->link->responder_streams, dslink_int_ref(rid),
                   refStream);

    ref_t *findref = dslink_map_remove_get(&link->requester_streams, &s->requester_rid);
    if (findref) {
        BrokerStream *oldstream = findref->data;
        if (oldstream->req_close_cb) {
            oldstream->req_close_cb(oldstream, link);
        }
        broker_stream_free(oldstream);
        dslink_decref(findref);
    }
    dslink_map_set(&link->requester_streams,
                   dslink_int_ref(s->requester_rid),
                   dslink_incref(refStream));

    send_invoke_request(ds, req, rid, out, permissionOnPath);
    return 0;
}