How to run the getRole command using pymongo? - mongodb

I want to check whether a role exists in a mongodb, before I create a new one . I tried to do it the following way:
result = self.client[database].command("getRole", name=app_name)
Unfortunately I get the following error:
msg = msg or "%s"
raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: no such command: 'getRole', bad cmd: '{ getRole: 1, name: "test" }'
I am referring to this database command: https://docs.mongodb.com/manual/reference/method/db.getRole/
For createRole I can execute the command: https://docs.mongodb.com/manual/reference/method/db.createRole/#db.createRole

Shell methods db.* are different from Database commands.
Using the roleInfo command you can get information for a particular role.
db.command({
'rolesInfo': {'role': 'noremove','db': 'test'},
'showPrivileges': True, 'showBuiltinRoles': True
})
The above command returns a result in this form when there is a matching role:
{'ok': 1.0,
'roles': [{'db': 'test',
'inheritedPrivileges': [{'actions': ['find', 'insert', 'update'],
'resource': {'collection': 'test', 'db': 'test'}}],
'inheritedRoles': [],
'isBuiltin': False,
'privileges': [{'actions': ['find', 'insert', 'update'],
'resource': {'collection': 'test', 'db': 'test'}}],
'role': 'noremove',
'roles': []}]}
When there is no matching role, you get this result:
{'ok': 1.0, 'roles': []}
Checking that a role exists falls to checking for the length of the "roles" list in the returned result as follow:
noremove_role = db.command({
'rolesInfo': {'role': 'noremove','db': 'test'},
'showPrivileges': True, 'showBuiltinRoles': True
})
if not len(noremove_role['roles']):
# create role
pass
Is there a better way?
Yes, in keeping with ask forgiveness not permission philosophy, create the role and handle the resulting exception from trying to add an existing role.
from pymongo.errors import DuplicateKeyError
import logging
logger = logging.getLogger()
try:
db.command(
'createRole', 'noremove',
privileges=[{
'actions': ['insert', 'update', 'find'],
'resource': {'db': 'test', 'collection': 'test'}
}],
roles=[])
except DuplicateKeyError:
logger.error('Role already exists.')
pass

Related

MongoDB how to create role on anydatabase, I need a restrited role to only showUsers Action on any databases

For known all databases (even with just users declared) I use with pymongo (pymongo==3.10.1 with mongodb 4.2)
db.command({'usersInfo': { 'forAllDBs': True },
'showCredentials': True})
this command need userAdminAnyDatabase builtin-role on client user.
But this role provide to much privileges. If someone crack the user password he can upgrade role to dbAdminAnyDatabases.
So I failed to create a any database role with authorization (role with only viewUser action on any databases) for userinfos previous command.
any can help me for this role definition?
You could try anyResource to get all the databases.
Thank's i create role :
with pymongo.MongoClient('mongodb://localhost:27017/',
username='SuperAdmin',
password='XXXXXXXXXX',
authSource='admin',
authMechanism='SCRAM-SHA-256') as client:
extendRole="showUsersAnyBase"
crole=client['admin'].command('rolesInfo',extendRole)
if reinit and extendRole in [x['role'] for x in crole['roles']]:
client['admin'].command('dropRole',extendRole)
if reinit or extendRole not in [x['role'] for x in crole['roles']]:
client['admin'].command({'createRole': extendRole,
'privileges': [{'resource': { 'anyResource': True },
'actions': [ "viewUser" ]}],
'roles':[ ]
})
create connector user:
usersInfos=client['admin'].command({'usersInfo': [{'user' : 'connector','db': 'admin'}]})
if reinitConnector and 'connector' in [x['user'] for x in usersInfos['users']]:
client['admin'].command('dropUser',"connector")
if reinitConnector or 'connector' not in [x['user'] for x in usersInfos['users']]:
client['admin'].command("createUser", "connector",
pwd="XXXXXXXXXX",
roles=[extendRole])
use the connector user with for userInfos command:
with pymongo.MongoClient('mongodb://localhost:27017/',
username='connector',
password='XXXXXXXXXX',
authSource='admin',
authMechanism='SCRAM-SHA-256') as client2:
usersInfos=client2['admin'].command({
'usersInfo': { 'forAllDBs': True },
'showCredentials': True
})
for user in usersInfos['users']:
print("user:",user['user'],
"db:",user['db'],
"roles:",[x['db']+'->'+x['role'] for x in user['roles']])
Works fine !!
and connector user can't grant role:
client2['admin'].command('grantRolesToUser','connector',
roles=['dbAdminAnyDatabase'])
throw exception :
.....
raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: not authorized on admin to execute command { grantRolesToUser: "connector", .....

MongoDB - Collection-level roles

I have a trouble.
I'm trying to apply a role to user.
I want the user only find, insert, remove and update specific collection
I'm doing this.
Create role:
db.createRole({role:'user_role_col',privileges:[{resource:{db:'something_else', collection: 'col_something_else'}, actions: ['find','remove','insert','update']}], roles: []});
.
Create user with that role:
db.createUser({user: 'user_col',pwd: '1234',roles: [{role: "user_role_col", db: "something_else"}]})
.
When I created role and user, I stay on something_else database (use something_else)
0 errors got, but I can only read col_something_else, I cannot remove, update, or insert :(
What am I doing wrong?
I believe the following commands replicates what you did. Here I'm creating the role and user in the test database:
> use test
> db.createRole({role: 'testRole', privileges: [{resource: {db:'test', collection:'test'}, actions:['find','update','insert','remove']}], roles: []})
> db.createUser({user:'testUser',pwd:'password',roles:[{role:'testRole', db:'test'}]})
I would then have to quit the mongo shell and re-authenticate using the new credentials. However, the authenticationDatabase parameter must point to the test database, since that's where I created the role and the user:
$ mongo -u testUser -p password --authenticationDatabase test
> db.test2.insert({a:1}) //try inserting to a non-"test" collection
unauthorized
> db.test2.find() //try find on a non-"test" collection
unauthorized
> db.test.insert({a:1}) //insert into "test" collection
Inserted 1 record(s)
> db.test.updateMany({},{$set:{a:2}}) //update "test" collection
{
"acknowledged": true,
"matchedCount": 1,
"modifiedCount": 1
}
> db.test.find() //find on "test" collection
{
"_id": ObjectId("5a0bcfa4322032cfcc3a69c6"),
"a": 2
}
> db.test.deleteOne({a:2}) //delete from "test" collection
{
"acknowledged": true,
"deletedCount": 1
}
> db.test.drop() //try to drop "test" collection
2017-11-15T16:32:07.715+1100 E QUERY [thread1] Error: drop failed: {
"ok": 0,
"errmsg": "not authorized on test to execute command { drop: \"test\" }",
"code": 13,
"codeName": "Unauthorized"
}
I found that the new custom role (testRole) is authorized correctly. This is using MongoDB 3.4.10.

mongodb authorization exception in JMeter : code13

In MongoDB 3.2 I've setup a user with rights:
db.createUser(
{
user: "username",
pwd: "pass",
roles: [ { role: "readWrite", db: "dbname" }]
}
)
db.auth("username", "pass" )
When I use the JMeter(2.13) to connect to the database (using Jmeter's elements MongoDB Source Config , MongoDB Script) and run a query like this:
db.mycollectionname.find()
I get this error:
error: { "$err" : "not authorized on dbname to execute command { $eval: \"db.mycollectionname.find()\", args: [] }" , "code" : 13}
While I have provided all the necessary details Server Address List , Database , User , Password to Jmeter's MongoDB Source Config , MongoDB Script respectively.
Any ideas what can be happening?
I had the same issue. I had to set up a user with eval permissions even though this is not recommended (even the admin user does not have these permissions).
Try that and change you script to look at the new user and it should work.

coffeescript error: 'unexpected .' for console.log

Have no idea why I am getting this error but my code:
angular.module('authAppApp')
.factory 'AuthService', (Session) ->
# Service logic
# ...
# Public API here
{
login: (creds)->
res =
id: 1,
user:
id: 1,
role: "admin"
Session.create(res.id, res.user.id, res.user.role)
return
}
Error:
[stdin]:30:14: error: unexpected .
Session.create(res.id, res.user.id, res.user.role)
^
This also happens with console.log
Why?
It looks like your indentation is off:
res =
id: 1,
user:
id: 1,
role: "admin"
Session.create(res.id, res.user.id, res.user.role)
return
The indentation of Session should match the indentation of res =. Otherwise, the coffeescript compiler will parse it as a property of the object you are setting res to. In particular, it's probably expecting a : and a value after Session.

symfony2 propel-bundle + postgres: syntax error near "."

this is for my login form which uses propel as user provider, I get this error which I can understand from, that identifiers are not quoted:
and error:
Unable to execute SELECT statement [SELECT user.id, user.username, user.password, user.email, user.type, user.first_name, user.last_name, user.national_code, user.personal_code, user.role, user.card, user.university_id, user.salt, user.active, user.created_at, user.updated_at FROM user WHERE user.username=:p1 LIMIT 1] [wrapped: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "." LINE 1: SELECT user.id, user.username, user.password, user.email, us... ^]
my propel configuration:
propel:
path: "%kernel.root_dir%/../vendor/propel"
phing_path: "%kernel.root_dir%/../vendor/phing"
logging: %kernel.debug%
dbal:
default_connection: default
connections:
default:
driver: %database_driver%
user: %database_user%
password: %database_password%
dsn: %database_driver%:host=%database_host%;dbname=%database_name%
options:
ATTR_PERSISTENT: false
attributes:
ATTR_EMULATE_PREPARES: true
settings:
charset: { value: UTF8 }
build_properties:
propel.database: %database_driver%
propel.database.url: ${propel.dsn}
propel.database.buildUrl: ${propel.database.url}
propel.database.createUrl: ${propel.database.buildUrl}
propel.database.user: %database_user%
propel.database.password: %database_password%
propel.platform.class: platform.${propel.database}Platform
propel.disableIdentifierQuoting: false
and also my provider config:
providers:
main:
propel:
class: National\PublicationBundle\Model\User
property: username
is something wrong with my config? I also found this on github and changed my code accordingly but it did change nothing, what I did:
\$sql = sprintf(
'$query',
implode(', ', array_map(function(\$e) { return '\"'.\$e.'\"' ; }, \$modifiedColumns)),
implode(', ', array_keys(\$modifiedColumns))
);
one more thing: when I generate sql wih php app/console propel:build:sql, sql codes are quoted correctly.
answer: user is a reserved word! so just changed it to users and solved! :\