Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
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'])
Ejemplo n.º 4
0
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))
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
    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()