Skip to content

Commit 3dcb037

Browse files
feat(ui): allow creating per-host, per-user and foreign policies (#320)
1 parent e2c1226 commit 3dcb037

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/pages/Policies.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Link } from 'react-router-dom';
1212
import { handleChange } from '../forms';
1313
import { OptionalDirectory } from '../forms/OptionalDirectory'
1414
import KopiaTable from '../utils/KopiaTable';
15-
import { CLIEquivalent, compare, isAbsolutePath, ownerName, policyEditorURL, redirect } from '../utils/uiutil';
15+
import { checkPolicyPath, CLIEquivalent, compare, isAbsolutePath, ownerName, policyEditorURL, redirect } from '../utils/uiutil';
1616

1717
const applicablePolicies = "Applicable Policies"
1818
const localPolicies = "Local Path Policies"
@@ -103,8 +103,10 @@ export class Policies extends Component {
103103
return;
104104
}
105105

106-
if (!isAbsolutePath(this.state.policyPath)) {
107-
alert("Policies can only be defined for absolute paths.");
106+
const error = checkPolicyPath(this.state.policyPath, this.state.localHost, this.state.localUsername);
107+
108+
if (error) {
109+
alert(error + "\nMust be either an absolute path, `user@host:/absolute/path`, `user@host` or `@host`. Use backslashes on Windows.");
108110
return;
109111
}
110112

@@ -294,4 +296,4 @@ export class Policies extends Component {
294296
<CLIEquivalent command="policy list" />
295297
</>;
296298
}
297-
}
299+
}

src/utils/uiutil.jsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,39 @@ export function isAbsolutePath(p) {
350350
return false;
351351
}
352352

353+
// Refer to kopia/snapshot/source.go:ParseSourceInfo
354+
export function checkPolicyPath(path) {
355+
if (path === "(global)") {
356+
return "Cannot create the global policy, it already exists.";
357+
}
358+
359+
// Check for a path before anything else and short-circuit
360+
// On Windows this avoids issues with the colon in C:/path
361+
if (isAbsolutePath(path)) {
362+
return null;
363+
}
364+
365+
const p1 = path.indexOf("@");
366+
const p2 = path.indexOf(":");
367+
368+
// user@host:path
369+
if (p1 > 0 && p2 > 0 && p1 < p2 && p2 < path.length) {
370+
path = path.substring(p2 + 1);
371+
} else if (p1 >= 0 && p2 < 0) {
372+
if (p1 + 1 < path.length) {
373+
// @host and user@host without path
374+
return null;
375+
}
376+
377+
return "Policies must have a hostname.";
378+
}
379+
380+
// We already know it isn't an absolute path,
381+
// nor is it a fully specified policy target,
382+
// so it's either completely invalid, or a relative path
383+
return "Policies can not be defined for relative paths.";
384+
}
385+
353386
export function errorAlert(err, prefix) {
354387
if (!prefix) {
355388
prefix = "Error"

0 commit comments

Comments
 (0)