Cloudant auth: lacks _users database - authentication

I'm getting set up with CouchDB on Cloudant, and I'm confused because Cloudant seems to do auth differently than regular CouchDB. Specifically, Cloudant seems to lack a _users database.
I read the Cloudant auth FAQ here, and it provided the following instructions:
Can I use CouchDB security features (_users database, security
objects, validation functions) on Cloudant?
Yes you can. If you want
to use the _users database you must first turn off Cloudant's own
security for the roles you want to manage via _users. To do this you
need to PUT a JSON document like the following to the _security
endpoint of the database (for example
https://USERNAME.cloudant.com/DATABASE/_security):
{ "cloudant": {
"nobody": ["_reader", "_writer", "_admin"] }, "readers": {
"names":["demo"],"roles":[] } }
These instructions worked fine, and allowed me to update the _security object of a database.
What wasn't clear was how to set up the _users database. It didn't exist automatically, so I tried creating it using a regular:
curl -X PUT $COUCH/_users
This worked fine, but when I attempt to add a new user to _users as follows:
curl -HContent-Type:application/json \
-vXPUT $COUCH/_users/org.couchdb.user:me \
--data-binary '{"_id": "org.couchdb.user:me","name": "me","roles": [],"type": "user","password": "pwd"}'
It appears to create the document correctly:
{"ok":true,"id":"org.couchdb.user:me","rev":"3-86c3801fdb8c32331f5f2580e861a765"}
But the new user in _users on Cloudant lacks a hashed password:
{
"_id": "org.couchdb.user:me",
"_rev": "3-86c3801fdb8c32331f5f2580e861a765",
"name": "me",
"roles": [
],
"type": "user",
"password": "pwd"
}
So when I attempt to authenticate at this user, I get the following error:
{"error":"bad_request","reason":"missing password_sha property in user doc"}
On my local CouchDB installation, creating a new user in _users would automatically create the hashed password:
{
"_id": "org.couchdb.user:test",
"_rev": "1-9c1c4360eba168468a37d7f623782d23",
"password_scheme": "pbkdf2",
"iterations": 10,
"name": "test",
"roles": [
],
"type": "user",
"derived_key": "4a122a20c1a8fdddb5307c29078e2c4269abffa5",
"salt": "36c0c05cf2a3ee321eabd10c46a8aa2a"
}
I tried copying the "_design/_auth" document from my local CouchDB installation to Cloudant, but the results are the same - no hashed password.
I appear to have gone off the rails at some point, but I'm not sure where this happened. How can I set up Cloudant to use the same kind of auth as regular CouchDB?

I found the answer via #cloudant IRC:
09:59 <+kocolosk> creating _users was the right thing to do
09:59 <+kocolosk> the API matches an older version of CouchDB where the passwords needed to hashed client-side
10:00 < jbeard> oh, I see
10:00 <+kocolosk> we're addressing that lack of support for automatic hashing
10:01 < jbeard> I'm trying to find documentation on client-side hashing in Couch.
10:02 < jbeard> What version of Couch is Cloudant aiming to be compatible with for _users?
10:04 <+kocolosk> jbeard: http://wiki.apache.org/couchdb/Security_Features_Overview
10:04 <+kocolosk> see "Generating password_sha (only applicable for 1.1.x and earlier)"
10:04 <+kocolosk> jbeard: this particular feature is the last bit where we are compatible with 1.1.x but not newer version
10:05 < jbeard> Excellent
10:05 < jbeard> That's what I needed to know

In fact, cloudant does not support the hash value generation.
I found this alternative that helps to use the _users db in the cloudant service...
https://github.com/doublerebel/cloudant-user

As of 2020, Cloudant hashes the password but doesn't use the same hashing algorithm as CouchDB currently does (pbkdf2). For better security and compatibilty, it is still advisable to generate the hash yourselves, e.g. with couch-pwd.
And instead of supplying
{ "cloudant": { "nobody": ["_reader", "_writer", "_admin"] }, "readers": { "names":["demo"],"roles":[] } }
The docs now suggest the couchdb_auth_only flag:
{
"couchdb_auth_only": true,
"members": {
"names": ["demo"],"roles":[]
},
"admins": {
"names": ["admin"],"roles":[]
}
}
But mind that the _admin role is not set automatically as in CouchDB 3.

Related

Disable a particular CouchDB user's password temporarily

Can I disable login for a particular CouchDB user while leaving their user doc in the authentication database?
This question is similar to How to temporarily disable particular user in couchdb?, but in that case the actual question was how to "temporarily disable particular user read/write access" [emphasis mine].
What I am trying to do is to completely prevent a user from login until a password is set.
The behavior isn't necessarily guaranteed by the CouchDB maintainers in the future, but inspired by the Unix password lockout feature it seems possible to do this in practice by replacing at least the derived_key field with a bogus value like "*" or "!".
For example, this user could login in by providing a certain password:
{
"_id": "org.couchdb.user:test",
"name": "test",
"roles": [],
"type": "user",
"password_scheme": "pbkdf2",
"iterations": 10,
"derived_key": "e7666ce1536488d8c0ceb2b2e9baf25d83e1d720",
"salt": "8b7ea88d05181c77553169354decb0b7"
}
By replacing the scheme-relevant fields with garbage data, the user is no longer able to log in while the CouchDB logs do not register any particular upset/crash:
{
"_id": "org.couchdb.user:test",
"name": "test",
"roles": [],
"type": "user",
"password_scheme": "pbkdf2",
"iterations": 10,
"derived_key": "!",
"salt": "-some other random nonce-"
}
I have not completely confirmed, though, how this gets handled inside of CouchDB. My read of the authenticate logic and how it interacts with the its pbkdf2 implementation is that the stored derived_key is compared as a raw byte string to the re-calculated one and thus there would be no way to generate a collision. So this should always disable the account. (As opposed to a situation where, say, the stored "!" is optimistically expected to be hex of a certainly length and gets quietly "coerced" to a buffer of all zeroes in any case where parsing fails or something…then it might be possible to find an input password such that the result looks correct. Leaving the salt set to a new random-but-valid nonce value would presumably keep a bypass like that prohibitive in practice.)

Token expires to SPO list: how can I make this persist for data refreshes?

I have a data connection in my Tabular model that is 2019/1500 compatibility level.
I have the model in VS 2019, and am refreshing data from an SPO list.
The issue is that when I go to refresh the token expires and I have to manually go to the data source connection credentials and refresh them.
How can I set this up so I don't have to use a token that expires?
Currently my connection details are listed as:
{
"protocol": "sharepoint-list",
"address": {
"url": "https://mysite.sharepoint.com/p/SomePage"
},
"authentication": null,
"query": null
}
and my security credentials:
{"AuthenticationKind":"OAuth2","Expires":"Mon, 13 Jul 2020 17:11:44 GMT","RefreshToken":"********","ProviderType":"SharePointAAD"}
Was struggling with the same problem and found : Using Sharepoint Lists in SSAS
Seems SSAS does not refresh the OAuth2 tokens. So the article has a Powershell script to refresh these.

How to auto login in Odoo's Web-module for res.user, not for res.partner?

I am trying to login using token-based Auth, because we are using Odoo-web module in mobile-app.
currently using GET-method url-passing approach which is "UNSECURE" on websites without SSL certificates and localhost-websites, as
myurl.com?username=foo&password=bar
How can I do that using Token based approach or passing credentials in POST-method, in Odoo-12?
Edit 1:
I found this authenticate() method in core-modules of odoo in http-controllers file and I am calling that only now, as:
request.session(db, username, password)
but I wanted it to be token based without hardcoding password as different passwords for different partners, which I can't hardcode and it's bad approach.
how can I do it by passing token and validating it?
You can use the authenticate endpoint provided by odoo to create a session for your api user.
In the following requests you then use the session id to process operations.
Example call to /web/session/authenticate with body:
{
"jsonrpc": "2.0",
"method": "call",
"id": 1,
"params": {
"db": "<YOUR-DB>",
"login": "<YOUR#LOGIN.COM>",
"password": "<YOUR-PASSWORD>"
}
}
You can find a description of the endpoints in https://github.com/odoo/odoo/blob/12.0/odoo/http.py

Wit AI response for API requests

I'm using wit ai for a bot and I think it's amazing. However, I must provide the customer with screens in my web app to train and manage the app. And here I found a big problem (or maybe I'm just lost). The documentation of the REST API is not enough to design a client that acts like the wit console (not even close). it's like a tutorial of what endpoints you can hit and an overview of the parameters, but no clean explanation of the structure of the response.
For example, there is no endpoint to get the insights edge. Also and most importantly, no clear documentation about the response structure when hitting the message endpoints (i.e. the structure the returned entities: are they prebuilt or not, and if they are, is the value a string or an object or array, and what the object might contain [e.g. datetime]). Also the problem of the deprecated guide and the new guide (the new guide should be done and complete by now). I'm building parts of the code based on my testing. Sometimes when I test something new (like adding a range in the datetime entity instead of just a value), I get an error when I try to set the values to the user since I haven't parsed the response right, and the new info I get makes me modify the DB structure at my end sometimes.
So, the bottom line, is there a complete reference that I can implement a complete client in my web app (my web app is in Java by the way and I couldn't find a client library that handles the latest version of the API)? Again, the tool is AWESOME but the documentation is not enough, or maybe I'm missing something.
The document is not enough of course but I think its pretty straightforward. And from what I read there is response structure under "Return the meaning of a sentence".
It's response in JSON format. So you need to decode the response first.
Example Request:
$ curl -XGET 'https://api.wit.ai/message?v=20170307&q=how%20many%20people%20between%20Tuesday%20and%20Friday' \
-H 'Authorization: Bearer $TOKEN'
Example Response:
{
"msg_id": "387b8515-0c1d-42a9-aa80-e68b66b66c27",
"_text": "how many people between Tuesday and Friday",
"entities": {
"metric": [ {
"metadata": "{'code': 324}",
"value": "metric_visitor",
"confidence": 0.9231
} ],
"datetime": [ {
"value": {
"from": "2014-07-01T00:00:00.000-07:00",
"to": "2014-07-02T00:00:00.000-07:00"
},
"confidence": 1
}, {
"value": {
"from": "2014-07-04T00:00:00.000-07:00",
"to": "2014-07-05T00:00:00.000-07:00"
},
"confidence": 1
} ]
}
}
You can read more about response structure under Return the meaning of a sentence

SoftLayer API: Does VSI flavor based order support specifying image_id

We want to programatically order VSI using the flavor (for example. Balanced type), however instead of using the standard os_code, we want the VSI to be created from a public image template (ie. CentOS7-ChangeStable). From the following doc it seems to be possible.
http://softlayer-python.readthedocs.io/en/latest/_modules/SoftLayer/managers/vs.html
However I tried but got the following error:
SoftLayer.exceptions.SoftLayerAPIError: SoftLayerAPIError(SoftLayer_Exception_InvalidValue): Invalid value provided for 'blockDevices'. Block devices may not be provided when using an image template.
Using slcli is failing as well with a different error:
# slcli vs create --hostname testvsi --domain vmonic.local --flavor BL2_4X8X100 --image 1cc8be72-f230-4ab9-b4b2-329c3e747853 --datacenter tok02 --private
This action will incur charges on your account. Continue? [y/N]: y
SoftLayerAPIError(SoftLayer_Exception_Public): Order is missing the following category: Operating System.
Please advice whether using "image_id" with "flavor" is supported in SL API / python API. Thanks!
this is an issue with the API, the python client uses the http://sldn.softlayer.com/reference/services/softlayer_virtual_guest/createObject method to create the VSI using RESTFul the same request would be something like this:
POST: https://$USERNAME:#APIKEY#api.softlayer.com/rest/v3.1/SoftLayer_Virtual_Guest/createObject
Payload:
{
"parameters": [{
"datacenter": {
"name": "tok02"
},
"domain": "softlayer.local",
"hourlyBillingFlag": true,
"blockDeviceTemplateGroup": {
"globalIdentifier": "1cc8be72-f230-4ab9-b4b2-329c3e747853"
},
"hostname": "rcabflav",
"privateNetworkOnlyFlag": true,
"supplementalCreateObjectOptions": {
"flavorKeyName": "BL2_4X8X100"
}
}]
}
and you will get the same error, I reported this error in Softlayer, if you want you can submit a ticket in softlayer and report it as well.