Hasura: Change permissions/schema in Hasura on runtime (dynamically) through API call - runtime

I'm trying to change permissions in Hasura on runtime (dynamically) through API call as follows:
curl --location --request POST 'https://hasura-0ccfcde0.nhost.app/v1/query' \
--header 'x-hasura-role: admin' \
--header 'Content-Type: application/json' \
--data-raw '{
"type" : "create_update_permission",
"args" : {
"table" : "customers",
"role" : "users",
"permission" : {
"check" : {
"user_id" : {
"_ne": ""
}
},
"filter" : {
"user_id" : "X-Hasura-User-Id"
},
"set":{
"name":"X-Hasura-User-Id"
},
"columns":["name","email"]
}
}
}'
But it returns with
{
"path": "$.args",
"error": "restricted access : admin only",
"code": "access-denied"
}
I'm following: https://hasura.io/docs/1.0/graphql/core/api-reference/schema-metadata-api/permission.html#create-update-permission
as you can see in the screenshot as well

It's not enough for you to just put admin in the x-hasura-role Header. If you think about it, this would be a huge vulnerability as anyone could issue this request against your backend. You've even shared the endpoint here in your example CURL request!
Instead, you need to pass the x-hasura-admin-secret Header with the value you've configured for your deployment. This value should be extremely guarded as anyone who has access to it has pretty wide open access to Hasura and potentially your entire Database at that point depending on what your Hasura configuration looks like
curl --location --request POST 'https://hasura-0ccfcde0.nhost.app/v1/query' \
--header 'x-hasura-admin-secret: whatever-your-configured-admin-secret-is' \
--header 'Content-Type: application/json' \
--data-raw '{
"type" : "create_update_permission",
"args" : {
"table" : "customers",
"role" : "users",
"permission" : {
"check" : {
"user_id" : {
"_ne": ""
}
},
"filter" : {
"user_id" : "X-Hasura-User-Id"
},
"set":{
"name":"X-Hasura-User-Id"
},
"columns":["name","email"]
}
}
}
Alternatively, making a call with a JWT that is signed with the admin role could also work if you don't want to directly use your Hasura secret. In this case you would set it in the Authorization header with the x-hasura-role: admin claim set

Related

Why do I have to PUT new documents to a nested URI, if mapping types have been removed?

I'm on Elasticsearch 7.14.0 where mapping types have been removed.
If I run the following:
curl -X PUT "localhost:9200/products/1?pretty" -H 'Content-Type: application/json' -d'
{
"name": "Toast"
}
'
I get
{
"error" : "Incorrect HTTP method for uri [/products/1?pretty] and method [PUT], allowed: [POST]",
"status" : 405
}
It seems that elastic wants me PUT it in an /index/type/ URI:
curl -X PUT "localhost:9200/pop/products/1?pretty" -H 'Content-Type: application/json' -d'
{
"name": "Toast"
}
'
{
"_index" : "pop",
"_type" : "products",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
I am wondering why I must have a nested URI indicating a type, if mapping types have been removed?
You have to add _doc to your put request call as shown below
curl -X PUT "localhost:9200/products/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
"name": "Toast"
}
'
As mentioned in elasticsearch official documentation after mapping types were removed in 7.x, you need to add , _doc (which does not represent a document type rather it represents the endpoint name) for the document index, get, and delete APIs

Elasticseach error with null value for dense vector datatype

I created an index with a dense_vector:
curl -X PUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d'
{
"mappings": {
"properties": {
"my_vector": {
"type": "dense_vector",
"dims": 3
}
}
}
}
'
When I index a document with a vector it works well:
curl -X PUT "localhost:9200/my_index/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
"my_vector" : [0.5, 10, 6]
}
'
BUT when I index a document with a null value for the vector it returns an error:
curl -X PUT "localhost:9200/my_index/_doc/2?pretty" -H 'Content-Type: application/json' -d'
{
"my_vector" : null
}
'
The error is:
{
"error" : {
"root_cause" : [
{
"type" : "parsing_exception",
"reason" : "Failed to parse object: expecting token of type [VALUE_NUMBER] but found [END_OBJECT]",
"line" : 5,
"col" : 1
}
],
"type" : "mapper_parsing_exception",
"reason" : "failed to parse",
"caused_by" : {
"type" : "parsing_exception",
"reason" : "Failed to parse object: expecting token of type [VALUE_NUMBER] but found [END_OBJECT]",
"line" : 5,
"col" : 1
}
},
"status" : 400
}
How can I handle null value for vector type in ES?
instead of setting it to null you can remove that field from that particular document which is equivalent to setting it as null using the followingrequest
curl --location --request POST 'http://{ip}:9200/my_index/_doc/{docId}/_update' \
--header 'Content-Type: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"script" : "ctx._source.remove(\"my_vector\")"
}'

Trying to define an index within Elasticsearch for py-image-dedup

I'm trying to get py-image-dedup working (https://github.com/markusressel/py-image-dedup) which requires an index built within elasticsearch. So far so good, all python code for py-image-dedup working and brew install elasticsearch all installed and working with the elasticsearch server happily working at local host address 127.0.0.1:9200
So now I try to build the index. The instructions say
curl -X PUT "127.0.0.1:9200/images?pretty" -H "Content-Type: application/json" -d "
{
\"mappings\": {
\"image\": {
\"properties\": {
\"path\": {
\"type\": \"keyword\",
\"ignore_above\": 256
}
}
}
}
}
which is clearly missing a " at the end and doesn't work in any variant as far as I can see.
I try
curl -X PUT "127.0.0.1:9200/images?pretty" -H "Content-Type: application/json" -d "{\"mappings\":{\"image\":{\"properties\":{\"path\":{\"type\":\"keyword\",\"ignore_above\":256}}}}} "
which looks sensible but get
{
"error" : {
"root_cause" : [
{
"type" : "mapper_parsing_exception",
"reason" : "Root mapping definition has unsupported parameters: [image : {properties={path={ignore_above=256, type=keyword}}}]"
}
],
"type" : "mapper_parsing_exception",
"reason" : "Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [image : {properties={path={ignore_above=256, type=keyword}}}]",
"caused_by" : {
"type" : "mapper_parsing_exception",
"reason" : "Root mapping definition has unsupported parameters: [image : {properties={path={ignore_above=256, type=keyword}}}]"
}
},
"status" : 400
}
and cannot for the life of me see why the index is not building correctly. Grateful for help.
you are trying to use types, which have been deprecated: https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html
Please drop the image type from your mapping definition.
curl -X PUT "127.0.0.1:9200/images?pretty" -H "Content-Type: application/json" -d "
{
\"mappings\": {
\"properties\": {
\"path\": {
\"type\": \"keyword\",
\"ignore_above\": 256
}
}
}
}

How to pass Authorisation token for all elasticsearch requests

I've setup a local elasticsearch node with kibana and have set
xpack.security.enabled: true
I require this as i plan to further add roles and I want to add document level security.
Both Kibana & Elastic search are up and running at their respective ports. I am struggling to understand how to I add a new document operating via console.
curl -X PUT "localhost:9200/customer/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
"name": "John Doe"
}
'
This fails with
{
"error" : {
"root_cause" : [
{
"type" : "security_exception",
"reason" : "missing authentication credentials for REST request [/customer/_doc/1?pretty]",
"header" : {
"WWW-Authenticate" : "Basic realm=\"security\" charset=\"UTF-8\""
}
}
],
"type" : "security_exception",
"reason" : "missing authentication credentials for REST request [/customer/_doc/1?pretty]",
"header" : {
"WWW-Authenticate" : "Basic realm=\"security\" charset=\"UTF-8\""
}
},
"status" : 401
}
Fair , I understand I need to get an auth token to pass to the curl. Which API retrives this and where can i find an example. I've tried this unsucessfully.
curl -X POST "localhost:9200/_security/oauth2/token?pretty" -H 'Content-Type: application/json' -d'
{
"grant_type" : "client_credentials"
"username" : "elastic",
"password" : "VKZjNLBVBSeLS08sHDIN"
}
'
The password was generated automatically while bringing up the node.
Thanks!
By curl:
curl -X PUT --basic -u {user}:{password} http://localhost:9200/customer/_doc/1?pretty
By http request in program:
1. Make the the base64 encoding for the string: ${user}:${password}
2. Add http header
key:"Authorization"
value:"Basic ${encode value in step 1}"
By curl with header:
curl -X PUT "localhost:9200/customer/_doc/1?pretty" -H 'Authorization:Basic ********' -H 'Content-Type: application/json' -d'
{
"name": "John Doe"
}
******** is the value of base64 encoding for the string: ${user}:${password}

Set up Flume HTTP agent on a URL?

I've been able to set up my HTTP source on a host and port like:
agent.sources=s1
...
agent.sources.s1.type=http
agent.sources.s1.bind=0.0.0.0
agent.sources.s1.port=5140
And I can, for example, POST a json document to it via:
curl -X POST -H 'Content-Type: application/json; charset=UTF-8' -d '[{
"headers" : { "ip" : "192.168.1.102", "host" :
"random_host.example.com" }, "body" : "random_body" }, { "headers" : {
"ip" : "192.168.1.102", "host" : "random_host.example.com" }, "body" :
"really_random_body" }]' http://hostname:port
However I would like to be able to POST a Json document to http://hostname.com:port/a/b/c/
How may I do this?

Resources