Exemple #1
0
class Db:

	def __init__(self, dburi):
		self.db = DBany(dburi)

	def _simple_and_cond(self, cond):
		if not cond:
			return None
		cnd = ['and', 1]
		for c in cond:
			cnd.append(('=', c[0], c[1]))
		return cnd

	def show(self, tab, cols, cond, limit=0):
		desc = self.db.describe(tab)
		if not cols:
			cols = desc.keys()
		head = [ desc[i] for i in cols ]
		cond = self._simple_and_cond(cond)
		return self.db.select(tab, cols, cond, limit), head

	def add(self, tab, ins):
		self.db.insert(tab, ins)

	def rm(self, tab, cond, limit=0):
		cond = self._simple_and_cond(cond)
		self.db.delete(tab, cond, limit)
Exemple #2
0
class Cred:
	TABLE = 'credentials'
	COLUMNS = ('auth_username', 'did', 'realm', 'uid', 'password', 'ha1', \
	           'ha1b', 'flags')
	COLIDXS = idx_dict(COLUMNS)
	FLAGIDX = COLIDXS['flags']

	def __init__(self, dburi, db=None):
		self.Domain_attrs = serctl.ctlattr.Domain_attrs
		self.Domain = serctl.ctldomain.Domain
		self.User = serctl.ctluser.User
		self.dburi = dburi
		if db is not None:
			self.db = db
		else:
			self.db = DBany(dburi)

	def default_flags(self):
		return str(LOAD_SER | FOR_SERWEB)

	def get_uid(self, username, realm):
		cnd, err = cond(CND_NO_DELETED, auth_username=username, realm=realm)
		rows = self.db.select(self.TABLE, 'uid', cnd)
		if not rows:
			raise Error (ENOREC, err)
		uids = uniq([ i[0] for i in rows ])
		if len(uids) > 1:
			raise Error (EDB, '%s@%s=%s' % (username, realm, str(uids)))
		uid = uids[0]
		return uid

	def get_uids_for_username(self, username):
		cnd, err = cond(CND_NO_DELETED, auth_username=username)
		rows = self.db.select(self.TABLE, 'uid', cnd)
		if not rows:
			raise Error (ENOREC, err)
		uids = [ i[0] for i in rows ]
		return uniq(uids)

	def exist(self, username, realm):
		cnd, err = cond(CND_NO_DELETED, auth_username=username, realm=realm)
		rows = self.db.select(self.TABLE, 'uid', cnd, limit=1)
		return rows != []

	def exist_uid(self, uid):
		cnd, err = cond(CND_NO_DELETED, uid=uid)
		rows = self.db.select(self.TABLE, 'uid', cnd, limit=1)
		return rows != []

	def exist_realm(self, realm):
		cnd, err = cond(CND_NO_DELETED, realm=realm)
		rows = self.db.select(self.TABLE, 'realm', cnd, limit=1)
		return rows != []

	def _show(self, cnd, err, cols, fformat, limit):
		if not cols:
			cols = self.COLUMNS
		cidx = col_idx(self.COLIDXS, cols)

		rows = self.db.select(self.TABLE, self.COLUMNS, cnd, limit)
		new_rows = []
		for row in rows:
			row[self.FLAGIDX] = cv_flags(fformat, row[self.FLAGIDX])
 			new_row = []
			for i in cidx:
				new_row.append(row[i])
			new_rows.append(new_row)
		desc = self.db.describe(self.TABLE)
		desc = [ desc[i] for i in cols ]
		return new_rows, desc

	def show(self,  realm=None, username=None, cols=None, fformat='raw', limit=0):
		cnd, err = cond(auth_username=username, realm=realm)
		return self._show(cnd, err, cols, fformat, limit)

	def show_uid(self, uid, cols=None, fformat='raw', limit=0):
		cnd, err = cond(uid=uid)
		return self._show(cnd, err, cols, fformat, limit)

	def hashes(self, username, realm, password):
		uri = '@'.join((username, realm))
		hash_src1  = ':'.join((username, realm, password))
		hash_src1b = ':'.join((uri, realm, password))
		ha1  = md5.new(hash_src1).hexdigest()
		ha1b = md5.new(hash_src1b).hexdigest()
		return (ha1, ha1b)


	def add(self, uid, username, did, realm, password, flags=None, force=False):
		dflags = self.default_flags()
		fmask  = parse_flags(flags)
		flags  = new_flags(dflags, fmask)

		if not did:
			do = self.Domain(self.dburi, self.db)
			try:
				did = do.get_did(realm)
			except:
				if force: return
				raise

		us = self.User(self.dburi, self.db)
		if not us.exist(uid) and not force:
			raise Error (ENOUSER, 'uid='+uid)

		if self.exist(username, realm):
			if force: return
			raise Error (EDUPL, )

		# compute hashes
		ha1, ha1b = self.hashes(username, realm, password)

		# add new cred
		ins = { 'uid' : uid, 'auth_username' : username, \
			'did' : did, 'realm' : realm, 'password' : password, \
			'ha1' : ha1, 'ha1b' : ha1b, 'flags' : flags \
		}
		self.db.insert(self.TABLE, ins)

	def _rm(self, cnd, err, force):
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows and not force:
			raise Error (ENOREC, err)
		for row in rows:
			nf = set_deleted(row[self.FLAGIDX])
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags': nf}, cnd)

	def rm(self, username, realm, force=False):
		try:
			uid = self.get_uid(username, realm)
		except:
			if force: return
			raise
		cnd, err = cond(CND_NO_DELETED, uid=uid, realm=realm)
		return self._rm(cnd, err, force)

	def rm_realm(self, realm, force=False):
		cnd, err = cond(CND_NO_DELETED, realm=realm)
		return self._rm(cnd, err, force)

	def rm_uid(self, uid, force=False):
		cnd, err = cond(CND_NO_DELETED, uid=uid)
		return self._rm(cnd, err, force)

	def change(self, username, realm, password=None, flags=None, force=False):
		upd = {}
		# username & realm is required for password change
		if password is not None:
			# compute hashes
			ha1, ha1b = self.hashes(username, realm, password)
			upd = {'ha1': ha1, 'ha1b': ha1b, 'password': password}

		fmask = parse_flags(flags)

		# update
		cnd, err = cond(CND_NO_DELETED, auth_username=username, realm=realm)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows and not force:
			raise Error (ENOREC, err)
		for row in rows:
			cnd = full_cond(self.COLUMNS, row)
			if flags is not None:
				nf = new_flags(row[self.FLAGIDX], fmask)
				upd['flags'] = nf
			self.db.update(self.TABLE, upd, cnd)

	def purge(self):
		self.db.delete(self.TABLE, CND_DELETED)
Exemple #3
0
class User:
	TABLE = 'user_attrs'
	COLUMNS = ('uid', 'name', 'value', 'type',  'flags')
	COLIDXS = idx_dict(COLUMNS)
	FLAGIDX = COLIDXS['flags']

	def __init__(self, dburi, db=None):
		self.Uri   = serctl.ctluri.Uri
		self.Cred  = serctl.ctlcred.Cred
		self.dburi = dburi
		if db is not None:
			self.db = db
		else:
			self.db = DBany(dburi)

	def default_flags(self):
		return '0'

	def is_used(self, uid):
		ur = self.Uri(self.dburi, self.db)
		cr = self.Cred(self.dburi, self.db)
		return ur.exist_uid(uid) or cr.exist_uid(uid)

	def get(self, uid):
		cnd, err = cond(CND_NO_DELETED, uid=uid)
		rows = self.db.select(self.TABLE, 'uid', cnd)
		if not rows:
			raise Error (ENOREC, err)
		return [ i[0] for i in rows ]

	def exist(self, uid):
		cnd, err = cond(CND_NO_DELETED, uid=uid)
		rows = self.db.select(self.TABLE, 'uid', cnd, limit=1)
		return rows != []

	def _try_rm_orphans(self, uid):
		ur = self.Uri(self.dburi, self.db)
		cr = self.Cred(self.dburi, self.db)
		try:
			ur.rm_uid(uid)
		except:
			pass
		try:
			cr.rm_realm(uid)
		except:
			pass

	def show(self, uid=None, cols=None, fformat='raw', limit=0):
		if not cols:
			cols = self.COLUMNS
		cidx = col_idx(self.COLIDXS, cols)

		cnd, err = cond(uid=uid)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd, limit)
		new_rows = []
		for row in rows:
			row[self.FLAGIDX] = cv_flags(fformat, row[self.FLAGIDX])
			new_row = []
			for i in cidx:
				new_row.append(row[i])
			new_rows.append(new_row)
		desc = self.db.describe(self.TABLE)
		desc = [ desc[i] for i in cols ]
		return new_rows, desc

	def add(self, uid, flags=None, force=False):
		dflags = self.default_flags()
		fmask  = parse_flags(flags)
		flags  = new_flags(dflags, fmask)

		# exist uid?
		cnd, err = cond(CND_NO_DELETED, uid=uid)
		rows = self.db.select(self.TABLE, 'uid', cnd, limit=1)
		if rows:
			if force: return
			raise Error (EDUPL, uid)

		# user add
		ins = {'uid': uid, 'name': 'datetime_created', \
		  'value': timestamp(), 'type': 2, 'flags': flags }
		self.db.insert(self.TABLE, ins)

	def rm(self, uid=None, force=False):
		if self.is_used(uid):
			if force:
				self._try_rm_orphans(uid)
			else:
				raise Error (EUSER, uid)

		# rm all uids (FIX: or only datetime_created?)
		cnd, err = cond(CND_NO_DELETED, uid=uid)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows and not force:
			raise Error (ENOREC, err)
		for row in rows:
			nf = set_deleted(row[self.FLAGIDX])
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags': nf}, cnd)

	def change(self, uid=None, flags=None, force=False):
		fmask = parse_flags(flags)

		cnd, err = cond(CND_NO_DELETED, uid=uid)

		# update flags
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows and not force:
			raise Error (ENOREC, err)
		for row in rows:
			nf = new_flags(row[self.FLAGIDX], fmask)
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags':nf}, cnd)

	def purge(self):
		self.db.delete(self.TABLE, CND_DELETED)
Exemple #4
0
class Domain:
	TABLE = 'domain'
	COLUMNS = ('did', 'domain', 'flags')
	COLIDXS = idx_dict(COLUMNS) # column index dict
	FLAGIDX = COLIDXS['flags']  # flags column index 

	def __init__(self, dburi, db=None):
		self.Uri   = serctl.ctluri.Uri
		self.Cred  = serctl.ctlcred.Cred
		self.Domain_attrs  = serctl.ctlattr.Domain_attrs
		self.dburi = dburi
		if db is not None:
			self.db = db
		else:
			self.db = DBany(dburi)

	def default_flags(self):
		return str(LOAD_SER | FOR_SERWEB)

	def get_did(self, domain):
		cnd, err = cond(CND_NO_DELETED, domain=domain)
		rows = self.db.select(self.TABLE, 'did', cnd, limit=1)
		if not rows:
			raise Error (ENOREC, err)
		return rows[0][0]

	def get_domains(self, did):
		cnd, err = cond(CND_NO_DELETED, did=did)
		rows = self.db.select(self.TABLE, 'domain', cnd)
		if not rows:
			raise Error (ENOREC, err)
		return [ row[0] for row in rows ]

	def get_domain(self, did):
		cnd, err = cond(CND_NO_DELETED, CND_CANONICAL, did=did)
		rows = self.db.select(self.TABLE, 'domain', cnd, limit=1)
		if not rows:
			cnd, err = cond(CND_NO_DELETED, did=did)
			rows = self.db.select(self.TABLE, 'domain', cnd, limit=1)
		if not rows:
			raise Error (ENOREC, err)
		return rows[0][0]

	def exist(self, did, domain):
		cnd, err = cond(CND_NO_DELETED, did=did, domain=domain)
		rows = self.db.select(self.TABLE, 'did', cnd, limit=1)
		return rows != []

	def exist_domain(self, domain):
		cnd, err = cond(CND_NO_DELETED, domain=domain)
		rows = self.db.select(self.TABLE, 'domain', cnd, limit=1)
		return rows != []

	def exist_did(self, did):
		cnd, err = cond(CND_NO_DELETED, did=did)
		rows = self.db.select(self.TABLE, 'did', cnd, limit=1)
		return rows != []

	def is_last_domain(self, did, domain):
		cnd, err = cond(CND_NO_DELETED, did=did)
		cnd.append(('!=', 'domain', domain))
		rows = self.db.select(self.TABLE, 'did', cnd, limit=1)
		return rows == []

	def is_used(self, did):
		ur = self.Uri(self.dburi, self.db)
		cr = self.Cred(self.dburi, self.db)
		return ur.exist_did(did) or cr.exist_realm(did)

	def _show(self, cnd, err, cols, fformat, limit):
		if not cols:
			cols = self.COLUMNS
		cidx = col_idx(self.COLIDXS, cols)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd, limit)
		new_rows = []
		for row in rows:
			row[self.FLAGIDX] = cv_flags(fformat, row[self.FLAGIDX])
			new_row = []
			for i in cidx:
				new_row.append(row[i])
			new_rows.append(new_row)
		desc = self.db.describe(self.TABLE)
		desc = [ desc[i] for i in cols ]
		return new_rows, desc

	def show_domain(self, domain=None, cols=None, fformat='raw', limit=0):
		cnd, err = cond(domain=domain)
		rows, desc = self._show(cnd, err, cols, fformat, limit)
		if domain and not rows:
			raise Error(ENODOMAIN, domain)
		return rows, desc

	def show_did(self, did=None, cols=None, fformat='raw', limit=0):
		cnd, err = cond(did=did)
		rows, desc = self._show(cnd, err, cols, fformat, limit)
		if did and not rows:
			raise Error(ENODID, did)
		return rows, desc

	def show_did_for_domain(self, domain=None, cols=None, fformat='raw', limit=0):
		if domain is None:
			return self.show_did(None, cols, fformat, limit)
		try:
			did = self.get_did(domain)
		except:
			if not cols:
				cols = self.COLUMNS
			desc = self.db.describe(self.TABLE)
			desc = [ desc[i] for i in cols ]
			return [], desc
		rows, desc = self.show_did(did, cols, fformat, limit)
		return rows, desc

	def add(self, did, domain, flags=None, force=False):
		dflags = self.default_flags()
		fmask  = parse_flags(flags)
		flags  = new_flags(dflags, fmask)
		canonical = is_canonical(flags)

		if self.exist(did, domain):
			if force: return
			raise Error (EDUPL, errstr(did=did, domain=domain))

		# set digest realm attr
		da = self.Domain_attrs(self.dburi, self.db)
		da.set_default(did, 'digest_realm', domain)

		# update canonical flag
		cnd, err = cond(CND_NO_DELETED, did=did)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		canon_exist = False
		for row in rows:
			if not is_canonical(row[self.FLAGIDX]):
				continue
			if not canonical:
				canon_exist = True
				break
			f = clear_canonical(row[self.FLAGIDX])
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags':f}, cnd)
		if not canonical and not canon_exist:
			flags = set_canonical(flags)

		# add new domain
		ins = { 'did' : did, 'domain' : domain, 'flags' : flags }
		self.db.insert(self.TABLE, ins)

	def rm(self, did, domain, force=False):
		if self.is_last_domain(did, domain):
			return self.rm_did(did, force)

		# is canonical?
		canon_deleted = True
		cnd, err = cond(CND_NO_DELETED, CND_CANONICAL, did=did, domain=domain)
		rows = self.db.select(self.TABLE, 'did', cnd, limit=1)
		if not rows:
			canon_deleted = False

		# remove
		cnd, err = cond(CND_NO_DELETED, did=did, domain=domain)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows:
			if force: return
			raise Error (ENOREC, err)
		for row in rows:
			nf = set_deleted(row[self.FLAGIDX])
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags': nf}, cnd)

		# set new canon flag
		if canon_deleted:
			cnd, err = cond(CND_NO_DELETED, did=did)
			rows = self.db.select(self.TABLE, self.COLUMNS, cnd, limit=1)
			if rows:
				nf = set_canonical(rows[0][self.FLAGIDX])
				cnd = full_cond(self.COLUMNS, rows[0])
				upd = {'flags': nf}
				self.db.update(self.TABLE, upd, cnd)

	def rm_did(self, did, force=False):
		da = self.Domain_attrs(self.dburi, self.db)

		if self.is_used(did):
			if force:
				self._try_rm_orphans(did)
			else:
				raise Error (EDOMAIN, 'did=%s' % did)

		da.rm_exist(did, 'digest_realm')

		# remove did
		cnd, err = cond(CND_NO_DELETED, did=did)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows:
			if force: return
			raise Error (ENOREC, err)
		for row in rows:
			nf = set_deleted(row[self.FLAGIDX])
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags': nf}, cnd)

	def rm_domain(self, domain, force=False):
		try:
			did = self.get_did(domain)
		except:
			if force: return
			raise
		self.rm(did, domain, force)

	def rm_did_for_domain(self, domain, force):
		try:
			did = self.get_did(domain)
		except:
			if force: return
			raise
		if self.is_used(did) and not force:
			raise Error (EDOMAIN, errstr(did=did))
		self.rm_did(did, force)

	def _try_rm_orphans(self, did):
		ur = self.Uri(self.dburi, self.db)
		cr = self.Cred(self.dburi, self.db)
		try:
			ur.rm_did(did)
		except:
			pass
		try:
			cr.rm_realm(did)
		except:
			pass

	def change_domain(self, domain, flags=None, force=False):
		upd = {}
		fmask = parse_flags(flags)
		nflags = new_flags(0, fmask)
		canonical = is_canonical(nflags)

		# get did
		try:
			did = self.get_did(domain)
		except:
			if force: return
			raise

		# clear canon
		if canonical:
			cnd, err = cond(CND_NO_DELETED, did=did)
			cnd.append(CND_CANONICAL)
			rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
			for row in rows:
				nf = clear_canonical(row[self.FLAGIDX])
				cnd = full_cond(self.COLUMNS, row)
				upd = {'flags':nf}
				self.db.update(self.TABLE, upd, cnd)

		# update flags
		cnd, err = cond(CND_NO_DELETED, domain=domain)
		rows = self.db.select(self.TABLE, self.COLUMNS, cnd)
		if not rows and not force:
			raise Error (ENOREC, err)
		for row in rows:
			nf = new_flags(row[self.FLAGIDX], fmask)
			cnd = full_cond(self.COLUMNS, row)
			self.db.update(self.TABLE, {'flags':nf}, cnd)


	def purge(self):
		self.db.delete(self.TABLE, CND_DELETED)