mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-03-31 07:12:23 -07:00
ALL:Authoritative plugin fields
This commit is contained in:
@@ -72,6 +72,7 @@ from .openapi.schemas import ( # noqa: E402 [flake8 lint suppression]
|
||||
BaseResponse, DeviceTotalsResponse,
|
||||
DeleteDevicesRequest, DeviceImportRequest,
|
||||
DeviceImportResponse, UpdateDeviceColumnRequest,
|
||||
LockDeviceFieldRequest,
|
||||
CopyDeviceRequest, TriggerScanRequest,
|
||||
OpenPortsRequest,
|
||||
OpenPortsResponse, WakeOnLanRequest,
|
||||
@@ -444,6 +445,62 @@ def api_device_update_column(mac, payload=None):
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@app.route("/device/<mac>/field/lock", methods=["POST"])
|
||||
@validate_request(
|
||||
operation_id="lock_device_field",
|
||||
summary="Lock/Unlock Device Field",
|
||||
description="Lock a field to prevent plugin overwrites or unlock it to allow overwrites.",
|
||||
path_params=[{
|
||||
"name": "mac",
|
||||
"description": "Device MAC address",
|
||||
"schema": {"type": "string"}
|
||||
}],
|
||||
request_model=LockDeviceFieldRequest,
|
||||
response_model=BaseResponse,
|
||||
tags=["devices"],
|
||||
auth_callable=is_authorized
|
||||
)
|
||||
def api_device_field_lock(mac, payload=None):
|
||||
"""Lock or unlock a device field by setting its source to LOCKED or USER."""
|
||||
data = request.get_json() or {}
|
||||
field_name = data.get("fieldName")
|
||||
should_lock = data.get("lock", False)
|
||||
|
||||
if not field_name:
|
||||
return jsonify({"success": False, "error": "fieldName is required"}), 400
|
||||
|
||||
# Validate that the field can be locked
|
||||
source_field = field_name + "Source"
|
||||
allowed_tracked_fields = {
|
||||
"devMac", "devName", "devLastIP", "devVendor", "devFQDN",
|
||||
"devSSID", "devParentMAC", "devParentPort", "devParentRelType", "devVlan"
|
||||
}
|
||||
if field_name not in allowed_tracked_fields:
|
||||
return jsonify({"success": False, "error": f"Field '{field_name}' cannot be locked"}), 400
|
||||
|
||||
device_handler = DeviceInstance()
|
||||
|
||||
try:
|
||||
# When locking: set source to LOCKED
|
||||
# When unlocking: check current value and let plugins take over
|
||||
new_source = "LOCKED" if should_lock else "NEWDEV"
|
||||
result = device_handler.updateDeviceColumn(mac, source_field, new_source)
|
||||
|
||||
if result.get("success"):
|
||||
action = "locked" if should_lock else "unlocked"
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": f"Field {field_name} {action}",
|
||||
"fieldName": field_name,
|
||||
"locked": should_lock
|
||||
})
|
||||
else:
|
||||
return jsonify(result), 400
|
||||
except Exception as e:
|
||||
mylog("error", f"Error locking field {field_name} for {mac}: {str(e)}")
|
||||
return jsonify({"success": False, "error": str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/mcp/sse/device/<mac>/set-alias', methods=['POST'])
|
||||
@app.route('/device/<mac>/set-alias', methods=['POST'])
|
||||
@validate_request(
|
||||
|
||||
@@ -58,6 +58,10 @@ class Device(ObjectType):
|
||||
devFirstConnection = String(description="Timestamp of first discovery")
|
||||
devLastConnection = String(description="Timestamp of last connection")
|
||||
devLastIP = String(description="Last known IP address")
|
||||
devPrimaryIPv4 = String(description="Primary IPv4 address")
|
||||
devPrimaryIPv6 = String(description="Primary IPv6 address")
|
||||
devVlan = String(description="VLAN identifier")
|
||||
devForceStatus = String(description="Force device status (online/offline/dont_force)")
|
||||
devStaticIP = Int(description="Static IP flag (0 or 1)")
|
||||
devScan = Int(description="Scan flag (0 or 1)")
|
||||
devLogEvents = Int(description="Log events flag (0 or 1)")
|
||||
@@ -86,6 +90,16 @@ class Device(ObjectType):
|
||||
devFQDN = String(description="Fully Qualified Domain Name")
|
||||
devParentRelType = String(description="Relationship type to parent")
|
||||
devReqNicsOnline = Int(description="Required NICs online flag")
|
||||
devMacSource = String(description="Source tracking for devMac (USER, LOCKED, NEWDEV, or plugin prefix)")
|
||||
devNameSource = String(description="Source tracking for devName")
|
||||
devFqdnSource = String(description="Source tracking for devFQDN")
|
||||
devLastIpSource = String(description="Source tracking for devLastIP")
|
||||
devVendorSource = String(description="Source tracking for devVendor")
|
||||
devSsidSource = String(description="Source tracking for devSSID")
|
||||
devParentMacSource = String(description="Source tracking for devParentMAC")
|
||||
devParentPortSource = String(description="Source tracking for devParentPort")
|
||||
devParentRelTypeSource = String(description="Source tracking for devParentRelType")
|
||||
devVlanSource = String(description="Source tracking for devVlan")
|
||||
|
||||
|
||||
class DeviceResult(ObjectType):
|
||||
|
||||
@@ -135,12 +135,26 @@ class DeviceInfo(BaseModel):
|
||||
devMac: str = Field(..., description="Device MAC address")
|
||||
devName: Optional[str] = Field(None, description="Device display name/alias")
|
||||
devLastIP: Optional[str] = Field(None, description="Last known IP address")
|
||||
devPrimaryIPv4: Optional[str] = Field(None, description="Primary IPv4 address")
|
||||
devPrimaryIPv6: Optional[str] = Field(None, description="Primary IPv6 address")
|
||||
devVlan: Optional[str] = Field(None, description="VLAN identifier")
|
||||
devForceStatus: Optional[str] = Field(None, description="Force device status (online/offline/dont_force)")
|
||||
devVendor: Optional[str] = Field(None, description="Hardware vendor from OUI lookup")
|
||||
devOwner: Optional[str] = Field(None, description="Device owner")
|
||||
devType: Optional[str] = Field(None, description="Device type classification")
|
||||
devFavorite: Optional[int] = Field(0, description="Favorite flag (0 or 1)")
|
||||
devPresentLastScan: Optional[int] = Field(None, description="Present in last scan (0 or 1)")
|
||||
devStatus: Optional[str] = Field(None, description="Online/Offline status")
|
||||
devMacSource: Optional[str] = Field(None, description="Source of devMac (USER, LOCKED, or plugin prefix)")
|
||||
devNameSource: Optional[str] = Field(None, description="Source of devName")
|
||||
devFqdnSource: Optional[str] = Field(None, description="Source of devFQDN")
|
||||
devLastIpSource: Optional[str] = Field(None, description="Source of devLastIP")
|
||||
devVendorSource: Optional[str] = Field(None, description="Source of devVendor")
|
||||
devSsidSource: Optional[str] = Field(None, description="Source of devSSID")
|
||||
devParentMacSource: Optional[str] = Field(None, description="Source of devParentMAC")
|
||||
devParentPortSource: Optional[str] = Field(None, description="Source of devParentPort")
|
||||
devParentRelTypeSource: Optional[str] = Field(None, description="Source of devParentRelType")
|
||||
devVlanSource: Optional[str] = Field(None, description="Source of devVlan")
|
||||
|
||||
|
||||
class DeviceSearchResponse(BaseResponse):
|
||||
@@ -259,6 +273,12 @@ class UpdateDeviceColumnRequest(BaseModel):
|
||||
columnValue: Any = Field(..., description="New value for the column")
|
||||
|
||||
|
||||
class LockDeviceFieldRequest(BaseModel):
|
||||
"""Request to lock/unlock a device field."""
|
||||
fieldName: str = Field(..., description="Field name to lock/unlock (devMac, devName, devLastIP, etc.)")
|
||||
lock: bool = Field(True, description="True to lock the field, False to unlock")
|
||||
|
||||
|
||||
class DeviceUpdateRequest(BaseModel):
|
||||
"""Request to update device fields (create/update)."""
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
Reference in New Issue
Block a user