proxmaster/clientsdb.py

152 lines
5.2 KiB
Python
Raw Normal View History

2016-02-15 05:30:43 -05:00
# -*- coding: utf-8
#
# manage clientsdb.json
#import site packages
import json
2016-03-03 20:51:54 -05:00
import hmac
import bcrypt
2016-02-15 05:30:43 -05:00
#import local packages
import ioconfig
import utils
def addclient(vmid, vmname, clientid, clientname, clientemail, vmpass):
""" add new client with the requested vm to the clientsdb.json """
2016-02-15 05:30:43 -05:00
clientsdb = readclientsdb()
2016-03-01 22:01:33 -05:00
2016-02-15 05:30:43 -05:00
if str(clientid) in clientsdb:
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('client[{}]> already exist. merging.'.format(clientid))
2016-02-15 05:30:43 -05:00
else:
2016-03-31 10:40:40 -04:00
ioconfig.logger.info('client[{}]> does not exist. creating...'.format(clientid))
#generate password and send it to the client
newpass = utils.genpassword(30)
2016-03-31 19:37:21 -04:00
ioconfig.logger.info('client[{}]> initial password is: {}'.format(clientid, newpass))
2016-03-31 10:40:40 -04:00
salt = bcrypt.gensalt()
2016-04-01 19:53:16 -04:00
b_newpass = newpass.encode('ascii')
encpasswd = bcrypt.hashpw(b_newpass, salt).decode('ascii')
2016-03-31 10:40:40 -04:00
vcard = { 'name':str(clientname), 'email':str(clientemail), 'encpasswd':str(encpasswd) }
2016-02-15 05:30:43 -05:00
newclient = { str(clientid):vcard }
clientsdb.update(newclient)
2016-03-31 19:37:21 -04:00
#Send initial email to the user as we will use the internal auth from now on.
###utils.sendmail(clientemail, 'W{} logged in.'.format)
#TODO: Sync with proxmaster-admin database (shell command could be used for this one)
ioconfig.logger.info('client[{}]> vmid {} is now owned by {} ({})'.format(clientid, vmid, clientemail, clientname))
2016-03-30 18:12:38 -04:00
#create initial vm template
vmdata = { 'hostname':str(vmname), 'vmid':str(vmid), 'ownerid':str(clientid) }
2016-02-15 05:30:43 -05:00
clientsdb[str(clientid)][str(vmid)] = vmdata
writeclientsdb(clientsdb)
2016-03-03 20:51:54 -05:00
2016-03-31 10:40:40 -04:00
def setencpasswd(clientemail, newpass):
2016-03-03 20:51:54 -05:00
""" setup a new management password """
salt = bcrypt.gensalt()
2016-04-01 19:53:16 -04:00
b_newpass = newpass.encode('ascii')
encpasswd = bcrypt.hashpw(b_newpass, salt).decode('ascii')
2016-03-03 20:51:54 -05:00
try:
clientsdb = readclientsdb()
2016-03-31 10:40:40 -04:00
path = utils.get_path(clientsdb, clientemail)
2016-03-03 20:51:54 -05:00
c_id = str(path[0])
#check the returned path with forward query
2016-03-31 10:40:40 -04:00
query = clientsdb[c_id]['email']
2016-03-31 19:37:21 -04:00
#ioconfig.logger.info('client[{}]> path={}'.format(c_id, str(path)))
2016-03-03 20:51:54 -05:00
except:
2016-04-08 10:48:18 -04:00
ioconfig.logger.critical('clients> client {} not found'.format(clientemail))
2016-03-03 20:51:54 -05:00
raise
2016-03-31 10:40:40 -04:00
if query != clientemail:
2016-03-31 19:37:21 -04:00
ioconfig.logger.critical('clients> test query returns different vmname! check clients db for consistency!')
2016-03-03 20:51:54 -05:00
raise
else:
2016-03-31 10:40:40 -04:00
clientsdb[c_id]['encpasswd'] = encpasswd
2016-03-31 19:37:21 -04:00
ioconfig.logger.info('client[{}]> {} password changed!'.format(c_id, clientemail))
2016-03-03 20:51:54 -05:00
writeclientsdb(clientsdb)
2016-03-31 10:40:40 -04:00
#TODO: Send new email to the client to notify the password change. This time sending the password in plain text is not needed.
2016-03-03 20:51:54 -05:00
2016-03-31 10:40:40 -04:00
def validate(clientemail, password):
""" return list of owned vmids or false if credentials match an user form the database.
useful for authing extrnal admin panels """
#1. search for the client
try:
clientsdb = readclientsdb()
path = utils.get_path(clientsdb, clientemail)
c_id = str(path[0])
2016-03-31 19:37:21 -04:00
#ioconfig.logger.info('client[{}]> path={}'.format(c_id, str(path)))
except:
2016-03-31 19:37:21 -04:00
ioconfig.logger.warning('clients> {} was not found in the database!'.format(clientemail))
#log bad ips here...
return False
2016-03-31 10:40:40 -04:00
#2. check the password
encpass = clientsdb[c_id]['encpasswd']
2016-04-01 19:53:16 -04:00
b_srvpass = password.encode('ascii')
b_encpass = encpass.encode('ascii')
2016-03-31 10:40:40 -04:00
if (hmac.compare_digest(bcrypt.hashpw(b_srvpass, b_encpass), b_encpass)):
#login successful
2016-03-31 19:37:21 -04:00
ioconfig.logger.info('client[{}]> {} logged in successfully'.format(c_id, clientemail))
2016-03-31 10:40:40 -04:00
#TODO: Notify admin
#3. generate vmlist to return the owned ids to the client.
return clientvms(clientsdb[c_id])
else:
2016-04-08 21:10:07 -04:00
ioconfig.logger.warning('clients> {} access denied!'.format(clientemail))
2016-03-31 10:40:40 -04:00
#cant compare password
#TODO: Log attempts and block.
return {}
def clientvms(vmlist):
""" generate vmlist """
#clear unused objects. perhaps there is a better way to do this but im kinda anxious today...
vmlist.pop('name')
vmlist.pop('email')
2016-03-31 19:37:21 -04:00
vmlist.pop('encpasswd')
2016-03-31 10:40:40 -04:00
2016-03-31 19:37:21 -04:00
response = {}
for vmid,data in vmlist.items():
2016-03-31 13:47:21 -04:00
response = { str(vmid):data }
return response
2016-02-15 05:30:43 -05:00
def vmowner(vmid, vmname, verbose):
""" find the owner of the vm """
clientsdb = readclientsdb()
try:
clientid = utils.find_rec(clientsdb, str(vmid))[0]['ownerid']
2016-02-15 05:30:43 -05:00
clientname = clientsdb[str(clientid)]['name']
except:
raise
clientid = '0' #unknown owner
clientname = 'unknown'
if verbose:
2016-04-08 10:48:18 -04:00
ioconfig.logger.info('client[{}]> {} is the owner of {} ({})'.format(str(clientid), clientname, str(vmid), vmname))
2016-02-15 05:30:43 -05:00
return clientid
def readclientsdb():
""" read client db """
try:
with open('clients.json') as dbr:
clientsdb = json.load(dbr)
dbr.close()
except:
clientsdb = {}
ioconfig.logger.warning('clients> initializing...')
#writeclientsdb(clientsdb)
return clientsdb
def writeclientsdb(clientsdb):
""" write db """
with open('clients.json', 'w') as dbw:
json.dump(clientsdb, dbw)
dbw.close()
2016-03-03 20:51:54 -05:00
if __name__ == '__main__':
2016-04-08 10:48:18 -04:00
setencpasswd('abc@xyz.com', 'todos')
2016-03-31 19:37:21 -04:00