mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-21 12:59:08 +02:00
Report the MDM VNC keys to the UI and bound the copyrect tile-hash map
This commit is contained in:
@@ -64,9 +64,13 @@ func BuildRestrictions(policy *Policy) Restrictions {
|
|||||||
r.MDM.SplitTunnelMode = policy.HasKey(KeySplitTunnelMode)
|
r.MDM.SplitTunnelMode = policy.HasKey(KeySplitTunnelMode)
|
||||||
r.MDM.SplitTunnelApps = policy.HasKey(KeySplitTunnelApps)
|
r.MDM.SplitTunnelApps = policy.HasKey(KeySplitTunnelApps)
|
||||||
r.MDM.RemoteJobsAllowed = policy.HasKey(KeyRemoteJobsAllowed)
|
r.MDM.RemoteJobsAllowed = policy.HasKey(KeyRemoteJobsAllowed)
|
||||||
|
r.MDM.DisableVNCApproval = policy.HasKey(KeyDisableVNCApproval)
|
||||||
if v, ok := policy.GetBool(KeyAllowServerSSH); ok {
|
if v, ok := policy.GetBool(KeyAllowServerSSH); ok {
|
||||||
r.MDM.AllowServerSSH = &v
|
r.MDM.AllowServerSSH = &v
|
||||||
}
|
}
|
||||||
|
if v, ok := policy.GetBool(KeyAllowServerVNC); ok {
|
||||||
|
r.MDM.AllowServerVNC = &v
|
||||||
|
}
|
||||||
if v, ok := policy.GetBool(KeyDisableAdvancedView); ok {
|
if v, ok := policy.GetBool(KeyDisableAdvancedView); ok {
|
||||||
r.MDM.DisableAdvancedView = &v
|
r.MDM.DisableAdvancedView = &v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package mdm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Every key the UI can be told about has to be mapped here. A field left out
|
||||||
|
// reports the key as unmanaged, so the desktop and mobile UIs offer a control
|
||||||
|
// the policy actually enforces, and the user's change is silently overridden.
|
||||||
|
func TestBuildRestrictions_MapsRemoteAccessKeys(t *testing.T) {
|
||||||
|
policy := NewPolicy(map[string]any{
|
||||||
|
KeyAllowServerSSH: true,
|
||||||
|
KeyAllowServerVNC: true,
|
||||||
|
KeyDisableVNCApproval: true,
|
||||||
|
KeyRemoteJobsAllowed: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
r := BuildRestrictions(policy)
|
||||||
|
|
||||||
|
require.NotNil(t, r.MDM.AllowServerSSH, "allowServerSSH must be reported as managed")
|
||||||
|
assert.True(t, *r.MDM.AllowServerSSH)
|
||||||
|
require.NotNil(t, r.MDM.AllowServerVNC, "allowServerVNC must be reported as managed")
|
||||||
|
assert.True(t, *r.MDM.AllowServerVNC)
|
||||||
|
assert.True(t, r.MDM.DisableVNCApproval, "disableVNCApproval must be reported as managed")
|
||||||
|
assert.True(t, r.MDM.RemoteJobsAllowed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// An unmanaged key stays nil/false so the UI leaves the control editable.
|
||||||
|
func TestBuildRestrictions_UnmanagedVNCKeys(t *testing.T) {
|
||||||
|
r := BuildRestrictions(NewPolicy(map[string]any{KeyAllowServerSSH: false}))
|
||||||
|
|
||||||
|
assert.Nil(t, r.MDM.AllowServerVNC, "an unset allowServerVNC must not read as managed")
|
||||||
|
assert.False(t, r.MDM.DisableVNCApproval)
|
||||||
|
}
|
||||||
@@ -126,13 +126,27 @@ func (d *copyRectDetector) updateDirty(frame *image.RGBA, w, h int, dirty [][4]i
|
|||||||
if tx+ts > w || ty+ts > h {
|
if tx+ts > w || ty+ts > h {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
idx := (ty/ts)*d.cols + (tx / ts)
|
||||||
|
pos := [2]int{tx, ty}
|
||||||
sum := d.hashTile(frame, tx, ty)
|
sum := d.hashTile(frame, tx, ty)
|
||||||
d.tileHash[(ty/ts)*d.cols+(tx/ts)] = sum
|
|
||||||
|
// Retire the hash this tile used to carry. Without this the map keeps
|
||||||
|
// one entry per distinct hash the tile has ever had, so a long session
|
||||||
|
// over changing content grows it without bound. Only drop the entry
|
||||||
|
// while it still points here: another tile may have claimed that hash
|
||||||
|
// since, and its mapping is live.
|
||||||
|
if old := d.tileHash[idx]; old != sum {
|
||||||
|
if owner, ok := d.prevTiles[old]; ok && owner == pos {
|
||||||
|
delete(d.prevTiles, old)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.tileHash[idx] = sum
|
||||||
// Latest-wins on collision: ensures the most recent owner of this
|
// Latest-wins on collision: ensures the most recent owner of this
|
||||||
// hash is the one we'll return on lookup. The previous owner's
|
// hash is the one we'll return on lookup. The previous owner's
|
||||||
// entry, if any, gets shadowed; if its content has changed it's
|
// entry, if any, gets shadowed; if its content has changed it's
|
||||||
// stale anyway and findTileMatch's verification will skip it.
|
// stale anyway and findTileMatch's verification will skip it.
|
||||||
d.prevTiles[sum] = [2]int{tx, ty}
|
d.prevTiles[sum] = pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ package server
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fillTile paints a tileSize×tileSize block of img at (x,y) with the colour
|
// fillTile paints a tileSize×tileSize block of img at (x,y) with the colour
|
||||||
@@ -223,3 +225,31 @@ func TestEncodeCopyRectBody_Layout(t *testing.T) {
|
|||||||
t.Fatalf("bad src bytes: % x", got[12:16])
|
t.Fatalf("bad src bytes: % x", got[12:16])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevTiles maps a tile hash to the position that carries it, so it can hold
|
||||||
|
// at most one entry per tile. Rehashing the same tile with fresh content must
|
||||||
|
// retire the hash it used to carry: a session over changing content otherwise
|
||||||
|
// accumulates one dead entry per distinct hash it has ever seen, for as long
|
||||||
|
// as the session lives.
|
||||||
|
func TestCopyRectDetector_PrevTilesStaysBounded(t *testing.T) {
|
||||||
|
const w, h = 128, 128 // 2x2 tiles at 64px
|
||||||
|
const ts = 64
|
||||||
|
const tiles = 4
|
||||||
|
|
||||||
|
frame := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
|
d := newCopyRectDetector(ts)
|
||||||
|
d.rebuild(frame, w, h)
|
||||||
|
|
||||||
|
dirty := [][4]int{{0, 0, ts, ts}, {ts, 0, ts, ts}, {0, ts, ts, ts}, {ts, ts, ts, ts}}
|
||||||
|
for i := range 200 {
|
||||||
|
for ty := range 2 {
|
||||||
|
for tx := range 2 {
|
||||||
|
fillTile(frame, tx*ts, ty*ts, ts, byte(i), byte(i*3), byte(tx+ty))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.updateDirty(frame, w, h, dirty)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.LessOrEqual(t, len(d.prevTiles), tiles,
|
||||||
|
"prevTiles must not grow past one entry per tile across repeated content changes")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user