1
votes

How can I verify if a given password matches with password from collection _users in arangoDB?

I know it can be done with Foxx app and arangosh but I am not using them as I am using my own API in python. So I don't know how to access to the password and check if matches with the given password without using Foxx or arangosh.

2

2 Answers

2
votes

You shouldn't rely on the system _users collection for your own user logic. The collection is strictly intended for ArangoDB's own user objects, not for application-level user management.

If you really do want to use ArangoDB's own user management, the best way to expose that when authentication is disabled is to use the org/arangodb/users module inside ArangoDB (e.g. using Foxx). The module provides an isValid method that takes a username and password and returns a boolean indicating whether the combination is valid or not:

var users = require('org/arangodb/users');
controller.post('/checkpw', function (req, res) {
  var credentials = req.params('credentials');
  res.json({
    valid: users.isValid(
      credentials.username,
      credentials.password
    )
  });
})
.bodyParam('credentials', joi.object({
  username: joi.string().required(),
  password: joi.string().required()
}).required());

The users HTTP API currently doesn't expose this method, so this is the only way to do it without relying on extremely unstable implementation details (the format of the _users collection has changed throughout 2.x and the collection may change again in the future).

EDIT: ArangoDB 3.0 will likely add an API route that returns a token (rather than cluttering up the database with session objects) when supplied with a valid username and password. This should make it easier to integrate with the built-in user management but the caveats remain the same: ArangoDB users are primarily intended for API-level authorization, not for application logic.

1
votes

The most easy way is to simply try a flat http request, and check for its result. The most simple call is _api/version; We prefix the database to find out whether the user is allowed to access a specific database. For this example we use _system; you need to replace it with the database you want to test the authentication against.

curl --dump - http://Joe:passvoid@localhost:8529/_db/_system/_api/version
GET /_db/_system/_api/version HTTP/1.1
Authorization: Basic Sm9lOnBhc3N2b2lk
User-Agent: curl/7.38.0
Host: localhost:8529
Accept: */*


HTTP/1.1 200 OK
Server: ArangoDB
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8
Content-Length: 37

{"server":"arango","version":"2.8.8"}

curl --dump - http://Joe:WRONGpassvoid@localhost:8529/_db/_system/_api/version 
GET /_db/_system/_api/version HTTP/1.1
Authorization: Basic Sm9lOldST05HcGFzc3ZvaWQ=
User-Agent: curl/7.38.0
Host: localhost:8529
Accept: */*

HTTP/1.1 401 Unauthorized
Server: ArangoDB
Content-Type: text/plain; charset=utf-8
Www-Authenticate: basic realm="arangodb/_system"
Connection: Keep-Alive
Content-Length: 0

So you need to check for the HTTP status code: 200 -> Success; 401 -> fail. See howto create authentication headers with python for details of the python specific http handling.