ptpb / pb

pb is a formerly-lightweight pastebin and url shortener
Other
549 stars 52 forks source link

option for config.yaml to runonce.py as admin with user credentials #130

Closed tristan-k closed 8 years ago

tristan-k commented 8 years ago

I'm using a shared-hoster with mongodb support. In order to run runonce.py successfully I'll have to authenticate as admin with the username and password, much like $ mongo admin --port 21080 -u annette_mongoadmin -p. How to do this with config.yaml?

buhman commented 8 years ago

Hmm. What if runonce.py accepted command-line arguments to override the config? Or would you rather have a separate config.yaml override thing?

tristan-k commented 8 years ago

I would prefer a separate config.yaml override thing :smiley:.

buhman commented 8 years ago

It sounds like you actually want/need your own custom runonce.py; something like this:

#!/usr/bin/env python3

from urllib.parse import urlparse
from pymongo import MongoClient

from pb.pb import load_yaml

config = load_yaml(None, 'config.yaml')

con = MongoClient(**config['MONGO_ADMIN'])
db = con[config['MONGO_DATABASE']]

up = urlparse(config['MONGO']['host'])

db.add_user(up.username, up.password)
db.authenticate(up.username, up.password)

db.pastes.ensure_index('digest', unique=True)
db.pastes.ensure_index('date')
db.pastes.ensure_index('label', unique=True, sparse=True)
db.pastes.ensure_index('private', sparse=True)

Then your config.yaml would look like this:

MONGO:
  host: 'mongodb://peasant:foopass@localhost'

MONGO_ADMIN:
  host: 'mongodb://admin:password@localhost'

MONGO_DATABASE: pb
buhman commented 8 years ago

If you like it, I suppose I can probably make the logic a bit more generalized (only attempt add_user shenanigans if MONGO_ADMIN exists) and throw this stuff into the upstream runonce.py

tristan-k commented 8 years ago

Sounds great! I really appreciate your time and effort! I'm fairly new to mongodb.

buhman commented 8 years ago

Hmm, I haven't played with mongodb's authentication much, and this is quite strange.

It seems the correct/better thing to do is make the grant from the admin database, and to have an admin user with both readWriteAnyDatabase and userAdminAnyDatabase. The thing I did early assumed an admin with only userAdminAnyDatabase.

buhman commented 8 years ago

https://github.com/ptpb/pb/commit/93539e2069106592c2cc3335c4e0ceb635b0c299

tristan-k commented 8 years ago

This method doesnt work for me.

 $ ./runonce.py admin mongodb://tristank_mongoadmin:XXXXXX@localhost:20705
 Traceback (most recent call last):
   File "./runonce.py", line 56, in <module>
     main(**vars(ns))
   File "./runonce.py", line 42, in main
     func(db)
   File "./runonce.py", line 35, in _admin
     add_config_user(db)
   File "./runonce.py", line 26, in add_config_user
     db.client.admin.add_user(*auth, roles=[{'role': 'readWrite', 'db': config['MONGO_DATABASE']}])
   File "/home/tristank/venv/pbenv/lib/python3.4/site-packages/pymongo/database.py", line 854, in add_user
     "instance of %s" % (string_type.__name__,))
 TypeError: name must be an instance of str