def check_context_auth(conn, user_id, domain, tenant_id): """Verify if users has jurisdiction over requested domain/tenant. The default Root user can assign any role to any user. Only users with Admin or Root roles are allowed to assign roles to users. This function will raise an error if the requesting user is not an admin user on the requested domain/tenant. Args: conn (obj): DB connection object. user_id (str): UUID of user. domain (str): Name of the domain. tenant_id (str): UUID of the tenant. """ req_user_id = g.current_request.token.user_id if req_user_id != '00000000-0000-0000-0000-000000000000': cur = conn.execute("SELECT id FROM luxon_role WHERE name=?", ('Administrator', )) admin_id = cur.fetchone()['id'] query, vals = build_where(user_id=req_user_id, domain=domain, tenant_id=tenant_id) query += " AND ('role_id'='00000000-0000-0000-0000-000000000000'" query += " OR role_id=?)" vals.append(admin_id) sql = "SELECT id FROM luxon_user_role WHERE " + query cur = conn.execute(sql, vals) if not cur.fetchone(): raise AccessDeniedError( "User %s not authorized in requested context " ": domain '%s', tenant_id '%s'" % (req_user_id, domain, tenant_id))
def rm_user_role(self, req, resp, id, role, domain=None, tenant_id=None): """ Remove a role associated to a user. Args: id (str): UUID of user. role (str): UUID of role. domain (str): Name of domain (defaults to None). Use the text "none" to indicate global domain when tenant_id is supplied. tenant_id (str): UUID of tenant (defaults to None). Returns: 200 OK with blank body if successful 404 Not Found if now entry was affected """ with db() as conn: where = { 'user_id': id, 'role_id': role, 'tenant_id': tenant_id, 'domain': domain } query, vals = build_where(**where) sql = "DELETE FROM luxon_user_role WHERE " + query cur = conn.execute(sql, vals) conn.commit() if not cur.rowcount: raise HTTPNotFound("No entry for %s" % where)
def disconnect(virtual_id, username=None): with db() as conn: nas_nodes = conn.execute( 'SELECT * FROM tradius_nas' + ' WHERE virtual_id = %s', virtual_id).fetchall() for nas in nas_nodes: sql = 'SELECT * FROM tradius_accounting WHERE ' where = {'nasipaddress': nas['server']} if username: where = {'username': username} where, values = build_where(**where) acct = conn.execute(sql + where, values).fetchall() for session in acct: pod(session['id'])
def check_unique(conn, id, role, domain, tenant_id): """Function to check if user role assignment is unique. Args: conn (obj): DB connection object. id (str): UUID of user. role (str): UUID of role. domain (str): Name of the domain. tenant_id (str): UUID of the tenant. """ sql = "SELECT id FROM luxon_user_role WHERE user_id=? AND role_id=? AND " vals = [id, role] query, addvals = build_where(domain=domain, tenant_id=tenant_id) sql += query cur = conn.execute(sql, (vals + addvals)) if cur.fetchone(): raise ValidationError("Entry for user '%s' role '%s' " "already exists on domain '%s'" " and tenant '%s'." % (id, role, domain, tenant_id))
def get_cdr(domain=None, tenant_id=None, username=None, session=False, page=1, limit=10, search=None): start = (page - 1) * limit where_query = {} if domain: where_query['tradius_nas.domain'] = domain if tenant_id: where_query['tenant_id'] = tenant_id if username: where_query['tradius_accounting.username'] = username if session: where_query['tradius_accounting.acctstoptime'] = None where, values = build_where(**where_query) if search: where2, values2 = build_like('OR', **search) if where2: if where: where += " AND (" + where2 + ")" else: where = where2 values += values2 with db() as conn: query = 'SELECT DISTINCT' + \ ' tradius_accounting.id as id,' + \ ' tradius_accounting.acctsessionid as acctsessionid,' + \ ' tradius_accounting.acctuniqueid as acctuniqueid,' + \ ' tradius_accounting.username as username,' + \ ' tradius_accounting.realm as realm,' + \ ' tradius_accounting.nasipaddress as nasipaddress,' + \ ' tradius_accounting.nasportid as nasportid,' + \ ' tradius_accounting.acctstarttime as acctstarttime,' + \ ' tradius_accounting.acctupdatetime as acctupdatetime,' + \ ' tradius_accounting.acctstoptime as acctstoptime,' + \ ' tradius_accounting.acctinterval as acctinterval,' + \ ' tradius_accounting.acctsessiontime as acctsessiontime,' + \ ' tradius_accounting.acctauthentic as acctauthentic,' + \ ' tradius_accounting.connectinfo_start as connectinfo_start,' + \ ' tradius_accounting.connectinfo_stop as connectinfo_stop,' + \ ' tradius_accounting.acctinputoctets as acctinputoctets,' + \ ' tradius_accounting.acctoutputoctets as acctoutputoctets,' + \ ' tradius_accounting.calledstationid as calledstationid,' + \ ' tradius_accounting.callingstationid as callingstationid,' + \ ' tradius_accounting.acctterminatecause as acctterminatecause,' + \ ' tradius_accounting.servicetype as servicetype,' + \ ' tradius_accounting.framedprotocol as framedprotocol,' + \ ' tradius_accounting.framedipaddress as framedipaddress' + \ ' FROM' + \ ' tradius_accounting INNER JOIN tradius_nas ON' + \ ' tradius_accounting.nasipaddress = tradius_nas.server' + \ ' INNER JOIN tradius_user ON' + \ ' tradius_nas.virtual_id = tradius_user.virtual_id' + \ ' AND' + \ ' tradius_accounting.username = tradius_user.username' if where: query += ' WHERE %s' % where query += ' LIMIT %s, %s' % (start, limit,) crsr = conn.execute(query, values) records = crsr.fetchall() return records
def action(ch, method, properties, msg): with db() as conn: if msg['type'] == 'append_pool': name = msg['pool']['name'] prefix = msg['pool']['prefix'] domain = msg['pool']['domain'] for ip in IPNetwork(prefix): try: conn.execute('INSERT INTO tradius_ippool' + ' (id, domain, pool_name, framedipaddress' + ', nasipaddress, username, pool_key)' + ' VALUES' + " (%s, %s, %s, %s, '', '', '')", (str(uuid4()), domain, name, ip.first(),)) conn.commit() except SQLIntegrityError as e: log.warning(e) elif msg['type'] == 'delete_pool': name = msg['pool']['name'] prefix = msg['pool']['prefix'] domain = msg['pool']['domain'] if prefix is None: where = {'pool_name': name, 'domain': domain} where, values = build_where(**where) sql = ('DELETE FROM tradius_ippool' + ' WHERE ') sql += where conn.execute(sql, values) conn.commit() else: for ip in IPNetwork(prefix): where = {'pool_name': name, 'domain': domain, 'framedipaddress': ip.first()} where, values = build_where(**where) sql = ('DELETE FROM tradius_ippool' + ' WHERE ') sql += where conn.execute(sql, values) conn.commit() elif msg['type'] == 'disconnect': nas_ip = msg['session'].get('NAS-IP-Address') result = conn.execute("SELECT * FROM tradius_nas" + " WHERE server = %s", nas_ip).fetchone() if result: secret_file = '%s/secret.tmp' % g.app.path packet_file = '%s/packet.tmp' % g.app.path with open('%s/secret.tmp' % g.app.path, 'w') as f: secret = result['secret'] f.write(secret) with open('%s/packet.tmp' % g.app.path, 'w') as f: for avp in msg['session']: f.write('%s = "%s"\n' % (avp, msg['session'][avp],)) if msg['type'] == 'disconnect': execute(['radclient', '-x', '%s:3799' % nas_ip, 'disconnect', '-f', packet_file, '-S', secret_file], check=False)
def commit(self): name = self.model_name if self.primary_key is None: raise KeyError("Model %s:" % name + " No primary key") from None key_id = self.primary_key.name transaction = self._pre_commit()[1] try: conn = db() for field in self.fields: # Another laggy bit of code to process. # However needed to check for duplicates with None values... if isinstance(self.fields[field], SQLModel.UniqueIndex): index_fields = {} error_fields = [] query = "SELECT count(id) as no FROM %s WHERE " % name if key_id in self._transaction: query += " %s != " % key_id query += "%s" oid = [self._transaction[key_id]] else: oid = [] for index_field in self.fields[field]._index: if index_field.name in self._transaction: if self._transaction[index_field.name]: error_fields.append(index_field.label) index_fields[index_field.name] = \ self._transaction[index_field.name] where, values = build_where(**index_fields) if oid and values: query += " AND " + where crsr = conn.execute(query, oid + values) res = crsr.fetchone() if res['no'] > 0: raise exceptions.ValidationError( " Duplicate Entry" + " (%s)" % ", ".join(error_fields)) from None if self._deleted: try: delete_id = transaction[key_id] sql = "DELETE FROM %s WHERE %s" % (self.model_name, key_id,) sql += " = %s" conn.execute(sql, delete_id) self._deleted = False self._created = True self._updated = False except SQLIntegrityError: raise ValidationError('In use by reference.') elif self._created: query = "INSERT INTO %s (" % name query += ','.join(transaction.keys()) query += ')' query += ' VALUES' query += ' (' placeholders = [] for ph in range(len(transaction)): placeholders.append('%s') query += ','.join(placeholders) query += ')' conn.execute(query, list(self._sql_parse_fields( transaction).values())) if isinstance(self.primary_key, SQLModel.Integer): self[self.primary_key.name] = conn.last_row_id() conn.commit() self._created = False self._updated = False self._deleted = False elif self._updated: update_id = transaction[key_id] sets = [] args = [] parsed = self._sql_parse_fields(self._new) for field in parsed: if self.primary_key.name != field: # We already check this on setitem # if self.fields[field].readonly: # self._new[field].error('readonly value') if self.fields[field].db: sets.append('%s' % field + ' = %s') args.append(parsed[field]) if len(sets) > 0: sets = ", ".join(sets) try: conn.execute('UPDATE %s' % name + ' SET %s' % sets + ' WHERE %s' % key_id + ' = %s', args + [update_id, ]) except SQLIntegrityError: raise ValidationError('In use by reference.') self._created = False self._updated = False self._deleted = False finally: conn.commit() conn.close() self._current = self._transaction self._new.clear()