20221221 sync deploy (#1285)

This commit is contained in:
Firstyear 2022-12-22 18:03:29 +10:00 committed by GitHub
parent c5bcc7aaf3
commit def8f3f1bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 126 additions and 77 deletions

View file

@ -23,7 +23,7 @@ ipa_ca = "/path/to/kanidm-ipa-ca.pem"
# The DN of an account with content sync rights. By default cn=Directory Manager has
# this access.
ipa_sync_dn = "cn=Directory Manager"
ipa_sync_pw = "pi9aix6balaqu8Maerah"
ipa_sync_pw = "directory manager password"
# The basedn to examine.
ipa_sync_base_dn = "dc=ipa,dc=dev,dc=kanidm,dc=com"

View file

@ -1,4 +1,4 @@
dn: cn=Retro Changelog Plugin,cn=plugins,cn=config
changetype: modify
add: nsslapd-include-suffix
replace: nsslapd-include-suffix
nsslapd-include-suffix: dc=ipa,dc=dev,dc=kanidm,dc=com

View file

@ -27,18 +27,44 @@ This example is located in [examples/kanidm-ipa-sync](https://github.com/kanidm/
In addition to this, you must make some configuration changes to FreeIPA to enable synchronisation.
You must modify the retro changelog plugin to include the full scope of the database suffix.
You can find the name of your 389 Directory Server instance with:
dsconf --list
Using this you can show the current status of the retro changelog plugin to see if you need
to change it's configuration.
dsconf <instance name> plugin retro-changelog show
dsconf slapd-DEV-KANIDM-COM plugin retro-changelog show
You must modify the retro changelog plugin to include the full scope of the database suffix so that
the sync tool can view the changes to the database. Currently dsconf can not modify the include-suffix
so you must do this manually.
You need to change the `nsslapd-include-suffix` to match your FreeIPA baseDN here. You can
access the basedn with:
ldapsearch -H ldaps://<IPA SERVER HOSTNAME/IP> -x -b '' -s base namingContexts
# namingContexts: dc=ipa,dc=dev,dc=kanidm,dc=com
You should ignore `cn=changelog` and `o=ipaca` as these are system internal namingContexts. You
can then create an ldapmodify like the following.
```
{{#rustdoc_include ../../../iam_migrations/freeipa/00config-mod.ldif}}
```
You must then restart your FreeIPA server.
And apply it with:
ldapmodify -f change.ldif -H ldaps://<IPA SERVER HOSTNAME/IP> -x -D 'cn=Directory Manager' -W
# Enter LDAP Password:
You must then reboot your FreeIPA server.
## Running the Sync Tool Manually
You can perform a dry run with the sync tool manually to check your configurations are
correct.
correct and that the tool can synchronise from FreeIPA.
kanidm-ipa-sync [-c /path/to/kanidm/config] -i /path/to/kanidm-ipa-sync -n
kanidm-ipa-sync -i /etc/kanidm/ipa-sync -n

View file

@ -327,12 +327,14 @@ impl fmt::Display for AuthType {
pub enum UiHint {
ExperimentalFeatures = 0,
PosixAccount = 1,
CredentialUpdate = 2,
}
impl fmt::Display for UiHint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
UiHint::PosixAccount => write!(f, "PosixAccount"),
UiHint::CredentialUpdate => write!(f, "CredentialUpdate"),
UiHint::ExperimentalFeatures => write!(f, "ExperimentalFeatures"),
}
}
@ -343,6 +345,7 @@ impl FromStr for UiHint {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"CredentialUpdate" => Ok(UiHint::CredentialUpdate),
"PosixAccount" => Ok(UiHint::PosixAccount),
"ExperimentalFeatures" => Ok(UiHint::ExperimentalFeatures),
_ => Err(()),

View file

@ -99,6 +99,10 @@ macro_rules! try_from_entry {
.copied()
.collect();
if !$value.attribute_equality("class", &PVCLASS_SYNC_OBJECT) {
ui_hints.insert(UiHint::CredentialUpdate);
}
if $value.attribute_equality("class", &PVCLASS_POSIXACCOUNT) {
ui_hints.insert(UiHint::PosixAccount);
}
@ -722,7 +726,8 @@ mod tests {
.expect("Unable to create uat");
// Check the ui hints are as expected.
assert!(uat.ui_hints.is_empty());
assert!(uat.ui_hints.len() == 1);
assert!(uat.ui_hints.contains(&UiHint::CredentialUpdate));
// Modify the user to be a posix account, ensure they get the hint.
let me_posix = unsafe {
@ -748,8 +753,9 @@ mod tests {
.to_userauthtoken(session_id, ct, AuthType::Passkey, None)
.expect("Unable to create uat");
assert!(uat.ui_hints.len() == 1);
assert!(uat.ui_hints.len() == 2);
assert!(uat.ui_hints.contains(&UiHint::PosixAccount));
assert!(uat.ui_hints.contains(&UiHint::CredentialUpdate));
// Add a group with a ui hint, and then check they get the hint.
let e = entry_init!(
@ -772,9 +778,10 @@ mod tests {
.to_userauthtoken(session_id, ct, AuthType::Passkey, None)
.expect("Unable to create uat");
assert!(uat.ui_hints.len() == 2);
assert!(uat.ui_hints.len() == 3);
assert!(uat.ui_hints.contains(&UiHint::PosixAccount));
assert!(uat.ui_hints.contains(&UiHint::ExperimentalFeatures));
assert!(uat.ui_hints.contains(&UiHint::CredentialUpdate));
assert!(idms_prox_write.commit().is_ok());
})

View file

@ -233,7 +233,7 @@ function addBorrowedObject(obj) {
}
function __wbg_adapter_48(arg0, arg1, arg2) {
try {
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h871c42aaca1d3703(arg0, arg1, addBorrowedObject(arg2));
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hdb7f5bd2101eb559(arg0, arg1, addBorrowedObject(arg2));
} finally {
heap[stack_pointer++] = undefined;
}
@ -261,11 +261,11 @@ function makeClosure(arg0, arg1, dtor, f) {
return real;
}
function __wbg_adapter_51(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h6073fca8e152ad8e(arg0, arg1, addHeapObject(arg2));
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hd6c53cf713a6c0ff(arg0, arg1, addHeapObject(arg2));
}
function __wbg_adapter_54(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h501c623b6f23b8ff(arg0, arg1, addHeapObject(arg2));
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h3b581d83a45c2264(arg0, arg1, addHeapObject(arg2));
}
/**
@ -345,6 +345,10 @@ async function load(module, imports) {
function getImports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbindgen_is_undefined = function(arg0) {
const ret = getObject(arg0) === undefined;
return ret;
};
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'number' ? obj : undefined;
@ -386,10 +390,6 @@ function getImports() {
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbindgen_is_undefined = function(arg0) {
const ret = getObject(arg0) === undefined;
return ret;
};
imports.wbg.__wbindgen_in = function(arg0, arg1) {
const ret = getObject(arg0) in getObject(arg1);
return ret;
@ -542,6 +542,29 @@ function getImports() {
imports.wbg.__wbg_log_4b5638ad60bdc54a = function(arg0) {
console.log(getObject(arg0));
};
imports.wbg.__wbg_getItem_845e475f85f593e4 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
}, arguments) };
imports.wbg.__wbg_removeItem_9da69ede4eea3326 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setItem_9c469d634d0c321c = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlFormElement_1c489ff7e99e43d3 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLFormElement;
} catch {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_value_ccb32485ee1b3928 = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@ -566,39 +589,6 @@ function getImports() {
imports.wbg.__wbg_set_992c1d31586b2957 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlFormElement_1c489ff7e99e43d3 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof HTMLFormElement;
} catch {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_getItem_845e475f85f593e4 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
}, arguments) };
imports.wbg.__wbg_removeItem_9da69ede4eea3326 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_setItem_9c469d634d0c321c = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_new_ca4d3a3eca340210 = function() { return handleError(function () {
const ret = new URLSearchParams();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_add_89a4f3b0846cf0aa = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_remove_1a26eb5d822902ed = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_pathname_78a642e573bf8169 = function(arg0, arg1) {
const ret = getObject(arg1).pathname;
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@ -620,6 +610,10 @@ function getImports() {
const ret = new URL(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_new_ca4d3a3eca340210 = function() { return handleError(function () {
const ret = new URLSearchParams();
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_HtmlInputElement_970e4026de0fccff = function(arg0) {
let result;
try {
@ -643,13 +637,11 @@ function getImports() {
imports.wbg.__wbg_setvalue_e5b519cca37d82a7 = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_create_53c6ddb068a22172 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).create(getObject(arg1));
return addHeapObject(ret);
imports.wbg.__wbg_add_89a4f3b0846cf0aa = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_get_da97585bbb5a63bb = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).get(getObject(arg1));
return addHeapObject(ret);
imports.wbg.__wbg_remove_1a26eb5d822902ed = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_href_90ff36b5040e3b76 = function(arg0, arg1) {
const ret = getObject(arg1).href;
@ -720,10 +712,14 @@ function getImports() {
imports.wbg.__wbg_focus_adfe4cc61e2c09bc = function() { return handleError(function (arg0) {
getObject(arg0).focus();
}, arguments) };
imports.wbg.__wbg_credentials_eab5c0bffc3e9cc5 = function(arg0) {
const ret = getObject(arg0).credentials;
imports.wbg.__wbg_create_53c6ddb068a22172 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).create(getObject(arg1));
return addHeapObject(ret);
};
}, arguments) };
imports.wbg.__wbg_get_da97585bbb5a63bb = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).get(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_getClientExtensionResults_0381c2792f96b9fa = function(arg0) {
const ret = getObject(arg0).getClientExtensionResults();
return addHeapObject(ret);
@ -757,6 +753,10 @@ function getImports() {
const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
};
imports.wbg.__wbg_credentials_eab5c0bffc3e9cc5 = function(arg0) {
const ret = getObject(arg0).credentials;
return addHeapObject(ret);
};
imports.wbg.__wbg_addEventListener_1fc744729ac6dc27 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
}, arguments) };
@ -786,6 +786,20 @@ function getImports() {
const ret = getObject(arg0).removeChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_instanceof_WorkerGlobalScope_16bb97a4549a3f21 = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof WorkerGlobalScope;
} catch {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_fetch_749a56934f95c96c = function(arg0, arg1) {
const ret = getObject(arg0).fetch(getObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_pushState_38917fb88b4add30 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
}, arguments) };
@ -1016,10 +1030,6 @@ function getImports() {
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
return ret;
}, arguments) };
imports.wbg.__wbg_stringify_d6471d300ded9b68 = function() { return handleError(function (arg0) {
const ret = JSON.stringify(getObject(arg0));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) {
const v = getObject(arg1);
const ret = typeof(v) === 'bigint' ? v : undefined;
@ -1040,16 +1050,16 @@ function getImports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper4814 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1014, __wbg_adapter_48);
imports.wbg.__wbindgen_closure_wrapper4824 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1020, __wbg_adapter_48);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper5000 = function(arg0, arg1, arg2) {
const ret = makeClosure(arg0, arg1, 1041, __wbg_adapter_51);
imports.wbg.__wbindgen_closure_wrapper5009 = function(arg0, arg1, arg2) {
const ret = makeClosure(arg0, arg1, 1044, __wbg_adapter_51);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper5658 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1290, __wbg_adapter_54);
imports.wbg.__wbindgen_closure_wrapper5669 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1294, __wbg_adapter_54);
return addHeapObject(ret);
};

View file

@ -237,6 +237,7 @@ impl ViewsApp {
let current_user_uat = uat.clone();
let ui_hint_experimental = uat.ui_hints.contains(&UiHint::ExperimentalFeatures);
let credential_update = uat.ui_hints.contains(&UiHint::CredentialUpdate);
// WARN set dash-body against body here?
html! {
@ -269,12 +270,14 @@ impl ViewsApp {
</li>
}
<li class="mb-1">
<Link<ViewRoute> classes="nav-link" to={ViewRoute::Security}>
<span data-feather="file"></span>
{ "Security" }
</Link<ViewRoute>>
</li>
if credential_update {
<li class="mb-1">
<Link<ViewRoute> classes="nav-link" to={ViewRoute::Security}>
<span data-feather="file"></span>
{ "Security" }
</Link<ViewRoute>>
</li>
}
if ui_hint_experimental {
<li class="mb-1">
@ -292,10 +295,10 @@ impl ViewsApp {
>{"Sign out"}</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
<button class="btn btn-outline-light" type="submit">{"Search"}</button>
</form>
// <form class="d-flex">
// <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
// <button class="btn btn-outline-light" type="submit">{"Search"}</button>
// </form>
</div>
</div>
</nav>