105 lines
4.1 KiB
Python
105 lines
4.1 KiB
Python
"""Changing how a PC is reached has to leave a record.
|
|
|
|
Editing a computer wrote an audit entry for its named fields and nothing at all
|
|
for two changes that matter most to anybody investigating later:
|
|
|
|
* the primary IP address - how the PC is found on the network
|
|
* the remote-access protocols and their ports - how somebody connects to it
|
|
|
|
Both are set on the same form, in the same request, and both were invisible
|
|
afterwards. A PC that moved address had no history of moving, and a PC that
|
|
gained a VNC listener had no record of gaining one.
|
|
"""
|
|
import pytest
|
|
|
|
from shopdb.api import db
|
|
|
|
|
|
@pytest.fixture
|
|
def pc(client, db, auth_headers):
|
|
from shopdb.core.models import AssetType, AssetStatus
|
|
|
|
if not AssetType.query.filter_by(assettype='computer').first():
|
|
db.session.add(AssetType(assettype='computer'))
|
|
if not AssetStatus.query.first():
|
|
db.session.add(AssetStatus(status='In Use'))
|
|
db.session.commit()
|
|
|
|
created = client.post('/api/computers', headers=auth_headers, json={
|
|
'assetnumber': 'AUDIT-PC-1',
|
|
'hostname': 'auditpc1',
|
|
'ipaddress': '10.20.30.40',
|
|
})
|
|
assert created.status_code == 201, created.get_json()
|
|
data = created.get_json()['data']
|
|
return data.get('computerid') or data['computer']['computerid']
|
|
|
|
|
|
def _entries(entityid):
|
|
from shopdb.core.models import AuditLog
|
|
|
|
return (AuditLog.query
|
|
.filter_by(entitytype='Computer', entityid=entityid)
|
|
.order_by(AuditLog.auditlogid.desc()).all())
|
|
|
|
|
|
def test_moving_a_pc_to_another_address_is_recorded(client, auth_headers, pc):
|
|
response = client.put('/api/computers/%d' % pc, headers=auth_headers,
|
|
json={'ipaddress': '10.20.30.99'})
|
|
assert response.status_code == 200, response.get_json()
|
|
|
|
latest = _entries(pc)[0]
|
|
assert 'ipaddress' in (latest.changes or {}), latest.changes
|
|
assert latest.changes['ipaddress']['old'] == '10.20.30.40'
|
|
assert latest.changes['ipaddress']['new'] == '10.20.30.99'
|
|
|
|
|
|
def test_an_unchanged_address_records_nothing(client, auth_headers, pc):
|
|
"""A PUT that re-sends the same value is not a change, and an audit log
|
|
full of non-events is one nobody reads."""
|
|
before = len(_entries(pc))
|
|
response = client.put('/api/computers/%d' % pc, headers=auth_headers,
|
|
json={'ipaddress': '10.20.30.40'})
|
|
assert response.status_code == 200
|
|
assert len(_entries(pc)) == before
|
|
|
|
|
|
def test_changing_the_remote_access_protocols_is_recorded(client, db,
|
|
auth_headers, pc):
|
|
from plugins.computers.models import AccessProtocol
|
|
|
|
rdp = AccessProtocol(name='RDP', scheme='rdp', linktemplate='rdp://{host}')
|
|
vnc = AccessProtocol(name='VNC', scheme='vnc', linktemplate='vnc://{host}')
|
|
db.session.add_all([rdp, vnc])
|
|
db.session.commit()
|
|
|
|
client.put('/api/computers/%d' % pc, headers=auth_headers,
|
|
json={'accessmethods': [{'protocolid': rdp.protocolid}]})
|
|
response = client.put('/api/computers/%d' % pc, headers=auth_headers,
|
|
json={'accessmethods': [
|
|
{'protocolid': vnc.protocolid,
|
|
'portoverride': 5999}]})
|
|
assert response.status_code == 200, response.get_json()
|
|
|
|
latest = _entries(pc)[0]
|
|
assert 'accessmethods' in (latest.changes or {}), latest.changes
|
|
change = latest.changes['accessmethods']
|
|
assert change['old'] == ['%d:default' % rdp.protocolid]
|
|
assert change['new'] == ['%d:5999' % vnc.protocolid]
|
|
|
|
|
|
def test_resending_the_same_protocols_records_nothing(client, db,
|
|
auth_headers, pc):
|
|
from plugins.computers.models import AccessProtocol
|
|
|
|
ssh = AccessProtocol(name='SSH', scheme='ssh', linktemplate='ssh://{host}')
|
|
db.session.add(ssh)
|
|
db.session.commit()
|
|
|
|
client.put('/api/computers/%d' % pc, headers=auth_headers,
|
|
json={'accessmethods': [{'protocolid': ssh.protocolid}]})
|
|
before = len(_entries(pc))
|
|
client.put('/api/computers/%d' % pc, headers=auth_headers,
|
|
json={'accessmethods': [{'protocolid': ssh.protocolid}]})
|
|
assert len(_entries(pc)) == before
|