Добавляем параметры OwnCloud/NextCloud к freeipa АЛД ПРО
Задача: расширить схему и добавить дополнительные параметры пользователям так, чтобы параметры можно было определять простыми LDAP-запросами, а управлять из интерфейса IPA
Покажу на примере атрибутов для работы с OwnCloud/NextCloud.
1. Создаем файл определения атрибутов схемы ```file.ldif```
dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( 1.3.6.1.4.1.49213.1.1.1 NAME 'owncloudEnabled'
DESC 'whether user or group should be available in owncloud'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
attributeTypes: ( 1.3.6.1.4.1.49213.1.1.2 NAME 'owncloudQuota'
DESC 'defines how much disk space is available for the user'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE)
-
add: objectclasses
objectClasses: ( 1.3.6.1.4.1.49213.1.2.1 NAME 'owncloudUser'
DESC 'A owncloud user'
SUP top AUXILIARY
MAY ( owncloudEnabled $ owncloudQuota )
)Создаем скрипт модуля ```userncenabled.py```
from ipaserver.plugins import user
from ipalib.parameters import Bool
from ipalib import _
user.user.takes_params = user.user.takes_params + (
Bool(
"owncloudenabled?",
cli_name="owncloudenabled",
label=_("Owncloud Share enabled?"),
doc=_(
"Whether or not a owncloud share is created for this user (default is false)."
),
default=False,
autofill=True,
),
)
user.user.default_attributes.append("owncloudenabled")
# pylint: disable-msg=unused-argument,invalid-name,line-too-long
def useradd_precallback(self, ldap, dn, entry, attrs_list, *keys, **options):
"""Callback for `register_pre_callback`.
See <https://github.com/freeipa/freeipa/blob/master/doc/guide/guide.org#extending-existing-object> for details.
"""
entry["objectclass"].append("ownclouduser")
return dn
user.user_add.register_pre_callback(useradd_precallback)
# pylint: disable-msg=unused-argument,invalid-name,line-too-long
def usermod_precallback(self, ldap, dn, entry, attrs_list, *keys, **options):
"""Callback for `register_pre_callback`.
See <https://github.com/freeipa/freeipa/blob/master/doc/guide/guide.org#extending-existing-object> for details.
"""
if "objectclass" not in entry.keys():
old_entry = ldap.get_entry(dn, ["objectclass"])
entry["objectclass"] = old_entry["objectclass"]
entry["objectclass"].append("ownclouduser")
return dn
user.user_mod.register_pre_callback(usermod_precallback)Создаем скрипт модуля ```userncquota.py```
from ipaserver.plugins import user
from ipalib.parameters import Str
from ipalib.text import _
user.user.takes_params = user.user.takes_params + (
Str(
"owncloudquota?",
cli_name="owncloudquota",
label=_("Owncloud Share Quota"),
doc=_(
"Defines Owncloud share quota in Bytes. "
'Allowed values are "none",'
'"default", e.g. "1024 MB" (default is "default").'
),
default="default",
autofill=True,
pattern="^(default|none|[0-9]+ [MGT]B)quot;,
pattern_errmsg="".join(
'may only be "none", '
'"default" or a number of mega-, giga- or terabytes (e.g. 1024 MB)'
),
),
)
user.user.default_attributes.append("owncloudquota")
def useradd_precallback(self, ldap, dn, entry, attrs_list, *keys, **options):
"""Callback for `register_pre_callback`.
See <https://github.com/freeipa/freeipa/blob/master/doc/guide/guide.org#extending-existing-object> for details.
"""
entry["objectclass"].append("ownclouduser")
return dn
user.user_add.register_pre_callback(useradd_precallback)
def usermod_precallback(self, ldap, dn, entry, attrs_list, *keys, **options):
if "objectclass" not in entry.keys():
old_entry = ldap.get_entry(dn, ["objectclass"])
entry["objectclass"] = old_entry["objectclass"]
entry["objectclass"].append("ownclouduser")
return dn
user.user_mod.register_pre_callback(usermod_precallback)Создаем скрипт модуля webUI ```userncenabled.js```
define([
'freeipa/phases',
'freeipa/user'],
function(phases, user_mod) {
function get_item(array, attr, value) {
for (var i=0,l=array.length; i<l; i++) {
if (array[i][attr] === value)
return array[i];
}
return null;
}
var nc_enabled_plugin = {};
nc_enabled_plugin.add_nc_enabled_pre_op = function() {
var facet = get_item(user_mod.entity_spec.facets, '$type', 'details');
var section = get_item(facet.sections, 'name', 'account');
section.fields.push({
$type: 'checkbox',
name: 'owncloudenabled',
label: 'Owncloud Share enabled',
flags: ['w_if_no_aci']
});
return true;
};
phases.on('customization', nc_enabled_plugin.add_nc_enabled_pre_op);
return nc_enabled_plugin;
});Создаем скрипт модуля webUI ```userncquota.js```
define([
'freeipa/phases',
'freeipa/user'],
function(phases, user_mod) {
function get_item(array, attr, value) {
for (var i=0,l=array.length; i<l; i++) {
if (array[i][attr] === value)
return array[i];
}
return null;
}
var nc_quota_plugin = {};
nc_quota_plugin.add_nc_quota_pre_op = function() {
var facet = get_item(user_mod.entity_spec.facets, '$type', 'details');
var section = get_item(facet.sections, 'name', 'account');
section.fields.push({
name: 'owncloudquota',
label: 'Owncloud Share Quota',
flags: ['w_if_no_aci']
});
return true;
};
phases.on('customization', nc_quota_plugin.add_nc_quota_pre_op);
return nc_quota_plugin;
});Добавляем в схему нужный класс и нужные атрибуты
ldapadd -H ldap://$HOSTNAME -D 'cn=Directory Manager' -W -f file.ldif
Проверяем, что класс добавился
ldapsearch -H ldap://$HOSTNAME -D 'cn=Directory Manager' -W -x -s base -b 'cn=schema' objectclasses | grep -i owncloud
Проверяем, что атрибут добавился
ldapsearch -H ldap://$HOSTNAME -D 'cn=Directory Manager' -W -x -s base -b 'cn=schema' attributetypes | grep -i owncloud
ipa config-mod --addattr=ipaUserObjectClasses=owncloudUser
Копируем скрипты и перезапускаем
cp usernc*.py /usr/lib/python3/dist-packages/ipaserver/plugins/ cd /usr/lib/python3/dist-packages/ipaserver/plugins/ python -m compileall usernc* && python -O -m compileall usernc* apachectl graceful
Копируем модули к WebUI и перезапускаем
mkdir /usr/share/ipa/ui/js/plugins/{userncenabled,userncquota}
cp userncenabled.js /usr/share/ipa/ui/js/plugins/userncenabled/
cp userncquota.js /usr/share/ipa/ui/js/plugins/userncquota/
apachectl gracefulПосле этого в UI FreeIpa можно добавлять\изменять параметры
А так можно определить через LDAP-запрос
ldapsearch -H ldap://$HOSTNAME -Y GSSAPI "uid=slakwik" -o ldif-wrap=no | grep own
Модификация несложная, но напомню, что самодельные модули между КД АЛД ПРО не копируются и нужно разложить эти python и js скрипты на все КД домена.