def log_add_account_to_org(request, organization, account): LogEntry.add_log_entry( request.account, u'edit-account-add-org', u'{actor} added user {object} to organization {target}', target=organization, object=account)
def test_get_auditlog_entries(self): modelname = 'blocked_reason' # Justification's db_table j1 = Justification.objects.create(name='j1') j2 = Justification.objects.create(name='j2') LogEntry.add_create_entry(self.justification, j1) LogEntry.add_log_entry( self.justification, u'greet', u'{actor} greets {object}', object=j2, subsystem="hello", ) LogEntry.add_log_entry( self.justification, u'deliver', u'{actor} delivers {object} to {target}', object=j1, target=j2, subsystem='delivery', ) entries = get_auditlog_entries(modelname=modelname) self.assertEqual(entries.count(), 3) entries = get_auditlog_entries(modelname=modelname, subsystem='hello') self.assertEqual(entries.count(), 1) entries = get_auditlog_entries(modelname=modelname, pks=[j1.pk]) self.assertEqual(entries.count(), 2)
def log_add_account_to_group(request, group, account): LogEntry.add_log_entry( request.account, u'edit-account-add-group', u'{actor} added user {object} to group {target}', target=group, object=account)
def set_ifalias(account, handler: ManagementHandler, interface, request): """Set ifalias on netbox if it is requested""" if 'ifalias' in request.POST: ifalias = request.POST.get('ifalias') if check_format_on_ifalias(ifalias): try: handler.set_interface_description(interface, ifalias) interface.ifalias = ifalias LogEntry.add_log_entry( account, u'set-ifalias', u'{actor}: {object} - ifalias set to "%s"' % ifalias, subsystem=u'portadmin', object=interface, ) _logger.info( '%s: %s:%s - ifalias set to "%s"', account.login, interface.netbox.get_short_sysname(), interface.ifname, ifalias, ) except ManagementError as error: _logger.error('Error setting port description: %s', error) messages.error(request, "Error setting port description: %s" % error) else: messages.error(request, "Wrong format on port description")
def set_vlan(account, fac, interface, request): """Set vlan on netbox if it is requested""" if 'vlan' in request.POST: vlan = int(request.POST.get('vlan')) try: if is_cisco(interface.netbox): # If Cisco and trunk voice vlan (not Cisco voice vlan), # we have to set native vlan instead of access vlan config = read_config() voice_activated = request.POST.get('voice_activated', False) if not is_cisco_voice_enabled(config) and voice_activated: fac.set_native_vlan(interface, vlan) else: fac.set_vlan(interface, vlan) else: fac.set_vlan(interface, vlan) interface.vlan = vlan LogEntry.add_log_entry( account, u'set-vlan', u'{actor}: {object} - vlan set to "%s"' % vlan, subsystem=u'portadmin', object=interface, ) _logger.info('%s: %s:%s - vlan set to %s', account.login, interface.netbox.get_short_sysname(), interface.ifname, vlan) except (SnmpError, TypeError) as error: _logger.error('Error setting vlan: %s', error) messages.error(request, "Error setting vlan: %s" % error)
def desudo(request): """Switches the current session to become the original user from before a call to sudo(). """ if SUDOER_ID_VAR not in request.session: # We are not sudoing return other_user = request.account original_user_id = request.session[SUDOER_ID_VAR] original_user = Account.objects.get(id=original_user_id) del request.session[ACCOUNT_ID_VAR] del request.session[SUDOER_ID_VAR] _set_account(request, original_user) _logger.info( 'DeSudo: "%s" no longer acting as "%s"', original_user, request.account ) _logger.debug( 'DeSudo: (session: %s, account: %s)', dict(request.session), request.account ) LogEntry.add_log_entry( original_user, 'desudo', '{actor} no longer sudoed as {target}', subsystem='auth', target=other_user, )
def handle_trunk_edit(request, agent, interface): """Edit a trunk""" native_vlan = int(request.POST.get('native_vlan', 1)) trunked_vlans = [int(vlan) for vlan in request.POST.getlist('trunk_vlans')] if should_check_access_rights(get_account(request)): # A user can avoid the form restrictions by sending a forged post # request Make sure only the allowed vlans are set old_native, old_trunked = agent.get_native_and_trunked_vlans(interface) allowed_vlans = [ v.vlan for v in find_allowed_vlans_for_user(get_account(request)) ] trunked_vlans = filter_vlans(trunked_vlans, old_trunked, allowed_vlans) native_vlan = (native_vlan if native_vlan in allowed_vlans else old_native) _logger.info('Interface %s - native: %s, trunk: %s', interface, native_vlan, trunked_vlans) LogEntry.add_log_entry( request.account, u'set-vlan', u'{actor}: {object} - native vlan: "%s", trunk vlans: "%s"' % (native_vlan, trunked_vlans), subsystem=u'portadmin', object=interface, ) if trunked_vlans: agent.set_trunk(interface, native_vlan, trunked_vlans) else: agent.set_access(interface, native_vlan)
def test_addLog_entry_before(self): LogEntry.add_log_entry(self.justification, u'actor test', u'blbl', before=1) l = LogEntry.objects.filter(verb='actor test').get() self.assertEqual(l.before, u'1') l.delete()
def logout(request): """Controller for doing a logout""" if request.method == 'POST' and 'submit_desudo' in request.POST: desudo(request) return HttpResponseRedirect(reverse('webfront-index')) else: account = request.account del request.session[ACCOUNT_ID_VAR] del request.account request.session.set_expiry(datetime.now()) request.session.save() LogEntry.add_log_entry(account, 'log-out', '{actor} logged out', before=account) return HttpResponseRedirect('/')
def token_expire(request, pk): """Expire a token :param pk: Primary key :type request: django.http.request.HttpRequest """ token = get_object_or_404(APIToken, pk=pk) token.expires = datetime.now() token.save() LogEntry.add_log_entry( request.account, 'edit-apitoken-expiry', '{actor} expired {object}', object=token) messages.success(request, 'Token has been manually expired') return redirect(token)
def do_login(request): """Do a login based on post parameters""" errors = [] form = LoginForm(request.POST) origin = request.POST.get('origin', '').strip() if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] try: account = auth.authenticate(username, password) except ldapauth.Error as error: errors.append('Error while talking to LDAP:\n%s' % error) else: if account: LogEntry.add_log_entry( account, 'log-in', '{actor} logged in', before=account ) try: request.session[ACCOUNT_ID_VAR] = account.id request.account = account except ldapauth.Error as error: errors.append('Error while talking to LDAP:\n%s' % error) else: _logger.info("%s successfully logged in", account.login) if not origin: origin = reverse('webfront-index') return HttpResponseRedirect(origin) else: _logger.info("failed login: %r", username) errors.append( 'Username or password is incorrect, or the ' 'account is locked.' ) # Something went wrong. Display login page with errors. return render( request, 'webfront/login.html', { 'form': form, 'errors': errors, 'origin': origin, }, )
def authenticate_remote_user(request): """Authenticate username from http header REMOTE_USER Returns: :return: If the user was authenticated, an account. If the user was blocked from logging in, False. Otherwise, None. :rtype: Account, False, None """ username = get_remote_username(request) if not username: return None # We now have a username-ish try: account = Account.objects.get(login=username) except Account.DoesNotExist: # Store the remote user in the database and return the new account account = Account(login=username, name=username, ext_sync='REMOTE_USER') account.set_password(fake_password(32)) account.save() _logger.info("Created user %s from header REMOTE_USER", account.login) template = 'Account "{actor}" created due to REMOTE_USER HTTP header' LogEntry.add_log_entry(account, 'create-account', template=template, subsystem='auth') return account # Bail out! Potentially evil user if account.locked: _logger.info("Locked user %s tried to log in", account.login) template = 'Account "{actor}" was prevented from logging in: blocked' LogEntry.add_log_entry(account, 'login-prevent', template=template, subsystem='auth') return False return account
def sudo(request, other_user): """Switches the current session to become other_user""" if SUDOER_ID_VAR in request.session: # Already logged in as another user. raise SudoRecursionError() if not is_admin(get_account(request)): # Check if sudoer is acctually admin raise SudoNotAdminError() original_user = request.account request.session[SUDOER_ID_VAR] = original_user.id _set_account(request, other_user) _logger.info('Sudo: "%s" acting as "%s"', original_user, other_user) _logger.debug('Sudo: (session: %s, account: %s)', dict(request.session), request.account) LogEntry.add_log_entry(original_user, 'sudo', '{actor} sudoed to {target}', subsystem='auth', target=other_user)
def set_vlan(account, handler: ManagementHandler, interface, request): """Set vlan on netbox if it is requested""" if 'vlan' in request.POST: try: vlan = int(request.POST.get('vlan')) except ValueError: messages.error( request, "Ignoring request to set vlan={}".format( request.POST.get('vlan')), ) return try: if is_cisco(interface.netbox): # If Cisco and trunk voice vlan (not Cisco voice vlan), # we have to set native vlan instead of access vlan voice_activated = request.POST.get('voice_activated', False) if not CONFIG.is_cisco_voice_enabled() and voice_activated: handler.set_native_vlan(interface, vlan) else: handler.set_vlan(interface, vlan) else: handler.set_vlan(interface, vlan) interface.vlan = vlan LogEntry.add_log_entry( account, u'set-vlan', u'{actor}: {object} - vlan set to "%s"' % vlan, subsystem=u'portadmin', object=interface, ) _logger.info( '%s: %s:%s - vlan set to %s', account.login, interface.netbox.get_short_sysname(), interface.ifname, vlan, ) except (ManagementError, TypeError) as error: _logger.error('Error setting vlan: %s', error) messages.error(request, "Error setting vlan: %s" % error)
def set_admin_status(handler: ManagementHandler, interface, request: HttpRequest): """Set admin status for the interface""" status_up = '1' status_down = '2' account = request.account if 'ifadminstatus' in request.POST: adminstatus = request.POST['ifadminstatus'] try: if adminstatus == status_up: LogEntry.add_log_entry( account, u'enable-interface', u'{actor} enabled interface {object}', subsystem=u'portadmin', object=interface, ) _logger.info( '%s: Setting ifadminstatus for %s to %s', account.login, interface, 'up', ) handler.set_interface_up(interface) elif adminstatus == status_down: LogEntry.add_log_entry( account, u'disable-interface', u'{actor} disabled interface {object}', subsystem=u'portadmin', object=interface, ) _logger.info( '%s: Setting ifadminstatus for %s to %s', account.login, interface, 'down', ) handler.set_interface_down(interface) except (ManagementError, ValueError) as error: messages.error(request, "Error setting ifadminstatus: %s" % error)
def account_organization_remove(request, account_id, org_id): """Controller for removing an organization from an account""" try: account = Account.objects.get(id=account_id) except Account.DoesNotExist: messages.error(request, 'Account %s does not exist.' % (account_id)) return HttpResponseRedirect(reverse('useradmin-account_list')) try: organization = account.organizations.get(id=org_id) except Organization.DoesNotExist: messages.error(request, 'Organization %s does not exist or it is not associated ' 'with %s.' % (org_id, account)) return HttpResponseRedirect(reverse('useradmin-account_detail', args=[account.id])) if request.method == 'POST': account.organizations.remove(organization) messages.success(request, 'Organization %s has been removed from account %s.' % (organization, account)) LogEntry.add_log_entry( request.account, u'edit-account-remove-org', u'{actor} removed user {object} from organization {target}', target=organization, object=account) return HttpResponseRedirect(reverse('useradmin-account_detail', args=[account.id])) context = { 'name': 'in %s from %s' % (organization, account), 'type': 'organization', 'action': 'remove organization membership', 'back': reverse('useradmin-account_detail', args=[account.id]), } context.update(DEFAULT_NAVPATH) return render(request, 'useradmin/delete.html', context)
def logout(request, sudo=False): """Log out a user from a request Returns a safe, public path useful for callers building a redirect.""" # Ensure that logout can safely be called whenever if not (hasattr(request, 'session') and hasattr(request, 'account')): _logger.debug('logout: not logged in') return None if sudo or request.method == 'POST' and 'submit_desudo' in request.POST: desudo(request) return reverse('webfront-index') else: account = request.account del request.session[ACCOUNT_ID_VAR] del request.account request.session.set_expiry(datetime.now()) request.session.save() _logger.debug('logout: logout %s', account.login) LogEntry.add_log_entry(account, 'log-out', '{actor} logged out', before=account) _logger.debug('logout: redirect to "/" after logout') return u'/'
def set_admin_status(fac, interface, request): """Set admin status for the interface :type fac: nav.portadmin.snmputils.SNMPFactory :type request: django.http.HttpRequest """ status_up = '1' status_down = '2' account = request.account if 'ifadminstatus' in request.POST: adminstatus = request.POST['ifadminstatus'] try: if adminstatus == status_up: LogEntry.add_log_entry( account, u'enable-interface', u'{actor} enabled interface {object}', subsystem=u'portadmin', object=interface, ) _logger.info('%s: Setting ifadminstatus for %s to %s', account.login, interface, 'up') fac.set_if_up(interface.ifindex) elif adminstatus == status_down: LogEntry.add_log_entry( account, u'disable-interface', u'{actor} disabled interface {object}', subsystem=u'portadmin', object=interface, ) _logger.info('%s: Setting ifadminstatus for %s to %s', account.login, interface, 'down') fac.set_if_down(interface.ifindex) except (SnmpError, ValueError) as error: messages.error(request, "Error setting ifadminstatus: %s" % error)
def test_add_log_entry_bad_template(self): LogEntry.add_log_entry(self.justification, u'bad template test', u'this is a {bad} template') l = LogEntry.objects.filter(verb='bad template test').get() self.assertEqual(l.summary, u'Error creating summary - see error log') l.delete()
def account_group_remove(request, account_id, group_id, caller='account'): """Controller for removing a group from an account :param caller: indicate if account or group is caller. Used to define redirect url """ if caller == 'account': back_url = reverse('useradmin-account_detail', args=[account_id]) list_redirect = HttpResponseRedirect(reverse('useradmin-account_list')) detail_redirect = HttpResponseRedirect(back_url) else: back_url = reverse('useradmin-group_detail', args=[group_id]) list_redirect = HttpResponseRedirect(reverse('useradmin-group_list')) detail_redirect = HttpResponseRedirect(back_url) try: account = Account.objects.get(id=account_id) except Account.DoesNotExist: messages.error(request, 'Account %s does not exist.' % (account_id)) return list_redirect try: group = account.accountgroup_set.get(id=group_id) except AccountGroup.DoesNotExist: messages.warning(request, 'Group %s does not exist or it is not ' 'associated with %s.' % (group_id, account)) return detail_redirect if group.is_protected_group(): messages.error(request, '%s can not be removed from %s as it is a ' 'protected group.' % (account, group)) return detail_redirect if group.is_admin_group() and account.is_admin_account(): messages.error( request, '%s can not be removed from %s.' % (account, group)) return detail_redirect if request.method == 'POST': account.accountgroup_set.remove(group) messages.success( request, '%s has been removed from %s.' % (account, group)) LogEntry.add_log_entry( request.account, u'edit-account-remove-group', u'{actor} removed user {object} from group {target}', target=group, object=account) return detail_redirect context = { 'name': '%s from the group %s' % (account, group), 'type': 'account', 'action': 'remove group member', 'back': back_url, } context.update(DEFAULT_NAVPATH) return render(request, 'useradmin/delete.html', context)
def test_add_log_entry_actor_only(self): LogEntry.add_log_entry(self.justification, u'actor test', u'actor "{actor}" only is tested') l = LogEntry.objects.filter(verb='actor test').get() self.assertEqual(l.summary, u'actor "testarossa" only is tested') l.delete()
def test_str(self): LogEntry.add_log_entry(self.justification, u'str test', 'foo') l = LogEntry.objects.filter(verb='str test').get() self.assertEqual(str(l), 'foo') l.delete()