Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package yast2-gpmc for openSUSE:Factory checked in at 2021-01-15 19:46:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-gpmc (Old) and /work/SRC/openSUSE:Factory/.yast2-gpmc.new.28504 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-gpmc" Fri Jan 15 19:46:38 2021 rev:8 rq:863189 version:1.5.1 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-gpmc/yast2-gpmc.changes 2019-09-30 15:59:15.925237946 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-gpmc.new.28504/yast2-gpmc.changes 2021-01-15 19:47:24.882127801 +0100 @@ -1,0 +2,7 @@ +Wed Jan 13 16:46:07 UTC 2021 - dmul...@suse.com + +- Fix unable to parse samba admx templates; (bsc#1180896); +- Removing ad-dc dependency breaks gpmc; (jsc#ECO-2527); +- 1.5.1 + +------------------------------------------------------------------- Old: ---- yast2-gpmc-1.5.0.tar.bz2 New: ---- yast2-gpmc-1.5.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-gpmc.spec ++++++ --- /var/tmp/diff_new_pack.L3G2T9/_old 2021-01-15 19:47:25.434128623 +0100 +++ /var/tmp/diff_new_pack.L3G2T9/_new 2021-01-15 19:47:25.438128629 +0100 @@ -1,7 +1,7 @@ # # spec file for package yast2-gpmc # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,17 +12,17 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: yast2-gpmc -Version: 1.5.0 +Version: 1.5.1 Release: 0 Summary: Group Policy Management Console for YaST License: GPL-3.0-only Group: Productivity/Networking/Samba -Url: https://github.com/yast/yast2-gpmc +URL: https://github.com/yast/yast2-gpmc Source: %{name}-%{version}.tar.bz2 @@ -36,6 +36,7 @@ Requires: krb5-client Requires: python3-ldap +Requires: samba-ad-dc Requires: samba-client Requires: samba-python3 >= 4.10.0 Requires: yast2 @@ -66,5 +67,6 @@ %{yast_desktopdir} %{yast_metainfodir} %license COPYING +%doc %{yast_docdir} %changelog ++++++ yast2-gpmc-1.5.0.tar.bz2 -> yast2-gpmc-1.5.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/.github/workflows/ci.yml new/yast2-gpmc-1.5.1/.github/workflows/ci.yml --- old/yast2-gpmc-1.5.0/.github/workflows/ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-gpmc-1.5.1/.github/workflows/ci.yml 2021-01-14 21:41:29.000000000 +0100 @@ -0,0 +1,38 @@ + +# See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions + +name: CI + +on: [push, pull_request] + +jobs: + + Package: + runs-on: ubuntu-latest + container: registry.opensuse.org/yast/head/containers/yast-ruby:latest + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + + - name: Package Build + run: yast-ci-ruby -o package + + # downloading the Docker image takes some time so bundling several fast + # checks into one job avoids that overhead + Checks: + runs-on: ubuntu-latest + container: registry.opensuse.org/yast/head/containers/yast-ruby:latest + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + + - name: Perl Syntax + run: yast-ci-ruby -o perl_syntax + + - name: POT Check + run: rake check:pot + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/.travis.yml new/yast2-gpmc-1.5.1/.travis.yml --- old/yast2-gpmc-1.5.0/.travis.yml 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,11 +0,0 @@ -sudo: required -language: bash -services: - - docker - -before_install: - - docker build -t yast2-gpmc-image . -script: - # the "yast-travis-cpp" script is included in the base yastdevel/cpp image - # see https://github.com/yast/docker-yast-cpp/blob/master/yast-travis-cpp - - docker run -it -e TRAVIS=1 -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" yast2-gpmc-image yast-travis-cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/Dockerfile new/yast2-gpmc-1.5.1/Dockerfile --- old/yast2-gpmc-1.5.0/Dockerfile 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/Dockerfile 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -FROM yastdevel/cpp -COPY . /usr/src/app diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/README.md new/yast2-gpmc-1.5.1/README.md --- old/yast2-gpmc-1.5.0/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-gpmc-1.5.1/README.md 2021-01-14 21:41:29.000000000 +0100 @@ -0,0 +1,6 @@ +# YaST - The Group Policy Management Console Module # + +[![Workflow Status](https://github.com/yast/yast2-gpmc/workflows/CI/badge.svg?branch=master)]( +https://github.com/yast/yast2-gpmc/actions?query=branch%3Amaster) +[![Jenkins Status](https://ci.opensuse.org/buildStatus/icon?job=yast-yast2-gpmc-master)]( +https://ci.opensuse.org/view/Yast/job/yast-yast2-gpmc-master/) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/package/yast2-gpmc.changes new/yast2-gpmc-1.5.1/package/yast2-gpmc.changes --- old/yast2-gpmc-1.5.0/package/yast2-gpmc.changes 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/package/yast2-gpmc.changes 2021-01-14 21:41:29.000000000 +0100 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Wed Jan 13 16:46:07 UTC 2021 - dmul...@suse.com + +- Fix unable to parse samba admx templates; (bsc#1180896); +- Removing ad-dc dependency breaks gpmc; (jsc#ECO-2527); +- 1.5.1 + +------------------------------------------------------------------- Fri Sep 27 21:18:31 UTC 2019 - dmul...@suse.com - Create a stub smb.conf for s3_lp if no smb.conf exists. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/package/yast2-gpmc.spec new/yast2-gpmc-1.5.1/package/yast2-gpmc.spec --- old/yast2-gpmc-1.5.0/package/yast2-gpmc.spec 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/package/yast2-gpmc.spec 2021-01-14 21:41:29.000000000 +0100 @@ -17,7 +17,7 @@ Name: yast2-gpmc -Version: 1.5.0 +Version: 1.5.1 Release: 0 Summary: Group Policy Management Console for YaST License: GPL-3.0-only @@ -41,6 +41,7 @@ Requires: yast2 Requires: yast2-python3-bindings >= 4.0.0 Requires: yast2-adcommon-python >= 1.0 +Requires: samba-ad-dc Provides: yast-gpmc = %{version} Obsoletes: yast-gpmc < %{version} @@ -66,5 +67,6 @@ %{yast_desktopdir} %{yast_metainfodir} %license COPYING +%doc %{yast_docdir} %changelog diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/src/include/gpmc/complex.py new/yast2-gpmc-1.5.1/src/include/gpmc/complex.py --- old/yast2-gpmc-1.5.0/src/include/gpmc/complex.py 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/src/include/gpmc/complex.py 2021-01-14 21:41:29.000000000 +0100 @@ -34,6 +34,9 @@ from samba.netcmd import gpo from samba.netcmd import CommandError from samba import NTSTATUSError, WERRORError +from samba.samdb import SamDB +from samba.auth import system_session +import ldapurl def open_bytes(filename): if six.PY3: @@ -534,7 +537,9 @@ super().__init__() self.sambaopts = SambaOptions(lp) self.credopts = CredentialsOptions(creds) - self.samdb = samdb + self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % lp.get('realm')).initializeUrl(), + session_info=system_session(), + credentials=creds, lp=lp) self.outf = StringIO() def samdb_connect(self): @@ -556,7 +561,9 @@ super().__init__() self.sambaopts = SambaOptions(lp) self.credopts = CredentialsOptions(creds) - self.samdb = samdb + self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % lp.get('realm')).initializeUrl(), + session_info=system_session(), + credentials=creds, lp=lp) self.outf = StringIO() def samdb_connect(self): @@ -575,7 +582,9 @@ super().__init__() self.sambaopts = SambaOptions(lp) self.credopts = CredentialsOptions(creds) - self.samdb = samdb + self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % lp.get('realm')).initializeUrl(), + session_info=system_session(), + credentials=creds, lp=lp) self.outf = StringIO() def samdb_connect(self): @@ -594,7 +603,9 @@ super().__init__() self.sambaopts = SambaOptions(lp) self.credopts = CredentialsOptions(creds) - self.samdb = samdb + self.samdb = SamDB(url=ldapurl.LDAPUrl('ldap://%s' % lp.get('realm')).initializeUrl(), + session_info=system_session(), + credentials=creds, lp=lp) self.outf = StringIO() def samdb_connect(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/src/include/gpmc/defaults.py new/yast2-gpmc-1.5.1/src/include/gpmc/defaults.py --- old/yast2-gpmc-1.5.0/src/include/gpmc/defaults.py 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/src/include/gpmc/defaults.py 2021-01-14 21:41:29.000000000 +0100 @@ -34,24 +34,52 @@ elif val_type == 'CheckBox': e.type = 4 e.data = 1 if val else 0 + entries = [] - for x in conf.entries: - if not (strcmp(x.keyname, reg_key) and strcmp(x.valuename, key)): - entries.append(x) - entries.append(e) + if val_type == 'ListBox': + for v in val: + e = preg.entry() + e.keyname = six.b(reg_key) + e.valuename = six.b(v) + e.type = 1 + e.data = six.b(v) + entries.append(e) + else: + for x in conf.entries: + if not (strcmp(x.keyname, reg_key) and strcmp(x.valuename, key)): + entries.append(x) + entries.append(e) + conf.num_entries = len(entries) conf.entries = entries -def get_admx_value(conf, reg_key, key): - for e in conf.entries: - if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key): - return e.data +def get_admx_value(conf, val_type, reg_key, key): + if val_type == 'ListBox': + ret = [] + for e in conf.entries: + if strcmp(e.keyname, reg_key): + if e.data.strip(): + ret.append(e.data) + return ret + else: + for e in conf.entries: + if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key): + return e.data return None -def get_admx_configured(conf, reg_key, key): - for e in conf.entries: - if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key): +def get_admx_configured(conf, val_type, reg_key, key): + if val_type == 'ListBox': + ret = [] + for e in conf.entries: + if strcmp(e.keyname, reg_key): + if e.data.strip(): + ret.append(e.data) + if len(ret) > 0: return True + else: + for e in conf.entries: + if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key): + return True return False def select_script(title, policy, conn): @@ -172,7 +200,7 @@ Policies = { 'comp_passwd' : { 'file' : '\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf', - 'opts' : (lambda inf_conf : { + 'opts' : (lambda inf_conf, label : { 'MinimumPasswordAge' : { 'values' : Policies['comp_passwd']['values']( inf_conf, 'MinimumPasswordAge', 'Minimum password age', @@ -262,7 +290,7 @@ }, 'comp_lockout' : { 'file' : '\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf', - 'opts' : (lambda inf_conf : { + 'opts' : (lambda inf_conf, label : { 'LockoutDuration' : { 'values' : Policies['comp_lockout']['values']( inf_conf, 'LockoutDuration', 'Account lockout duration', @@ -322,7 +350,7 @@ }, 'comp_krb' : { 'file' : '\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf', - 'opts' : (lambda inf_conf : { + 'opts' : (lambda inf_conf, label : { 'MaxTicketAge' : { 'values' : Policies['comp_krb']['values']( inf_conf, 'MaxTicketAge', 'Maximum lifetime for user ticket', @@ -402,7 +430,7 @@ }, 'comp_env_var' : { 'file': '\\MACHINE\\Preferences\\EnvironmentVariables\\EnvironmentVariables.xml', - 'opts' : (lambda xml_conf : { + 'opts' : (lambda xml_conf, label : { a.attrib['name']: { 'values' : Policies['comp_env_var']['values'](a), } for a in xml_conf.findall('EnvironmentVariable') @@ -471,7 +499,7 @@ }, 'comp_scripts_startup': { 'file' : '\\MACHINE\\Scripts\\scripts.ini', - 'opts' : (lambda inf_conf : { + 'opts' : (lambda inf_conf, label : { option : { 'values' : Policies['comp_scripts_startup']['values'](inf_conf, option), } for option in iter_scripts_conf(inf_conf, 'Startup') @@ -508,7 +536,7 @@ }, 'comp_scripts_shutdown': { 'file' : '\\MACHINE\\Scripts\\scripts.ini', - 'opts' : (lambda inf_conf : { + 'opts' : (lambda inf_conf, label : { option : { 'values' : Policies['comp_scripts_shutdown']['values'](inf_conf, option), } for option in iter_scripts_conf(inf_conf, 'Shutdown') @@ -545,7 +573,7 @@ }, 'comp_software_install': { 'file' : 'CN=Packages,CN=Class Store,CN=Machine,%s', - 'opts' : (lambda ldap_conf : { + 'opts' : (lambda ldap_conf, label : { option : { 'values' : Policies['comp_software_install']['values'](ldap_conf, option) } for option in ldap_conf.keys() @@ -593,7 +621,7 @@ }, 'user_internet_maint_conn' : { 'file': '\\USER\\MICROSOFT\\IEAK\\install.ins', - 'opts' : (lambda ins_conf : { + 'opts' : (lambda ins_conf, label : { 'Proxy Settings' : { 'values' : { 'Name' : { @@ -834,7 +862,7 @@ }, 'user_internet_maint_urls' : { 'file': '\\USER\\MICROSOFT\\IEAK\\install.ins', - 'opts' : (lambda ins_conf : { + 'opts' : (lambda ins_conf, label : { 'Important URLs' : { 'values' : { 'Name' : { @@ -902,7 +930,7 @@ }, 'user_internet_maint_links' : { 'file': '\\USER\\MICROSOFT\\IEAK\\install.ins', - 'opts' : (lambda ins_conf : { + 'opts' : (lambda ins_conf, label : { # need to handle these in a sub folder, and not like the others, since you can add multiple url links option : { 'values' : Policies['user_internet_maint_links']['values'](ins_conf, option), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-gpmc-1.5.0/src/include/gpmc/dialogs.py new/yast2-gpmc-1.5.1/src/include/gpmc/dialogs.py --- old/yast2-gpmc-1.5.0/src/include/gpmc/dialogs.py 2019-09-27 23:28:34.000000000 +0200 +++ new/yast2-gpmc-1.5.1/src/include/gpmc/dialogs.py 2021-01-14 21:41:29.000000000 +0100 @@ -61,16 +61,19 @@ conf = Policies[policy]['new']() if str(ret) == 'policy_table': selection = UI.QueryWidget(str(ret), 'CurrentItem') - values = Policies[policy]['opts'](conf)[selection]['values'] + values = Policies[policy]['opts'](conf, policy)[selection]['values'] elif str(ret) == 'add_policy': values = Policies[policy]['add'](conf) UI.SetApplicationTitle('%s Properties' % selection) UI.OpenDialog(self.__change_setting(values)) + list_results = None while True: subret = UI.UserInput() if str(subret) == 'ok_change_setting' or str(subret) == 'apply_change_setting': for k in values.keys(): - if 'configurable' in values[k]['input'] and values[k]['input']['configurable']: + if list_results: + value = list_results + elif 'configurable' in values[k]['input'] and values[k]['input']['configurable']: configured = UI.QueryWidget('configured_%s' % k, 'Value') if configured or configured == None: value = UI.QueryWidget('entry_%s' % k, 'Value') @@ -95,6 +98,8 @@ for k in others.keys(): UI.ReplaceWidget('text_entry_%s' % k, self.__button_entry(k, values, others[k])) continue + elif str(subret) == 'show': + list_results = self.__change_list(values) if str(subret) == 'cancel_change_setting' or str(subret) == 'ok_change_setting': UI.CloseDialog() UI.SetApplicationTitle('Group Policy Management Editor') @@ -107,6 +112,73 @@ return Symbol(ret) + def __change_list(self, values): + head = values['value']['input']['options']['present'] if values['value']['input']['options'] and 'present' in values['value']['input']['options'] else '' + vals = values['value']['get'] + items = [] + for i in range(0, len(vals)): + items.append(Item(Id(i), vals[i])) + dialog = MinHeight(20, MinWidth(50, HBox(HSpacing(), VBox( + VSpacing(), + Table(Id('values_table'), Opt('notify'), Header(head), items), + VSpacing(), + Right(HBox( + PushButton(Id('ok_list_item'), 'OK'), + PushButton(Id('cancel_list_item'), 'Cancel'), + PushButton(Id('add_list_item'), 'Add...'), + PushButton(Id('remove_list_item'), 'Remove'), + )), + VSpacing(), + ), HSpacing() ))) + UI.OpenDialog(dialog) + while True: + subret = UI.UserInput() + if str(subret) == 'cancel_list_item': + UI.CloseDialog() + return None + elif str(subret) == 'add_list_item': + item = self.__add_item() + vals = UI.QueryWidget('values_table', 'Items') + items = [] + for i in range(0, len(vals)): + items.append(Item(Id(i), vals[i][1])) + items.append(Item(Id(i+1), item)) + UI.ChangeWidget('values_table', 'Items', items) + elif str(subret) == 'remove_list_item': + highlighted = UI.QueryWidget('values_table', 'CurrentItem') + vals = UI.QueryWidget('values_table', 'Items') + items = [Item(Id(i[0][0]), i[1]) for i in vals if i[0][0] != highlighted] + UI.ChangeWidget('values_table', 'Items', items) + elif str(subret) == 'ok_list_item': + out = UI.QueryWidget('values_table', 'Items') + UI.CloseDialog() + return [i[1] for i in out] + + def __add_item(self): + dialog = HBox( + HSpacing(), + VBox( + Label('Enter the item to be added:'), + TextEntry(Id('add_item'), Opt('hstretch'), ''), + ), + HSpacing(), + VBox( + PushButton(Id('ok_add_item'), 'OK'), + PushButton(Id('cancel_add_item'), 'Cancel'), + ), + HSpacing(), + ) + UI.OpenDialog(dialog) + while True: + subret = UI.UserInput() + if str(subret) == 'cancel_add_item': + UI.CloseDialog() + return None + elif str(subret) == 'ok_add_item': + ret = UI.QueryWidget('add_item', 'Value') + UI.CloseDialog() + return ret + def __button_entry(self, k, values, value): return TextEntry(Id('entry_%s' % k), Opt('hstretch'), values[k]['title'], value) @@ -126,6 +198,7 @@ k = value[0] if not value[-1]['input']: continue + summary = value[-1]['input']['options']['present'] if value[-1]['input']['options'] and 'present' in value[-1]['input']['options'] else '' if strcmp(value[-1]['input']['type'], 'TextEntry'): configurable = Empty() configured = value[-1]['get'] != None @@ -166,23 +239,36 @@ items.append(Top(MinWidth(30, Left( ReplacePoint(Id('int_field_%s' % k), VBox( configurable, + Label(summary), IntField(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], 0, 999999999, value[-1]['get'] if value[-1]['get'] else 0) )) )))) elif strcmp(value[-1]['input']['type'], 'CheckBox'): if 'configurable' in value[-1]['input'] and value[-1]['input']['configurable']: disp = value[-1]['valstr'](value[-1]['get']) - items.append(Top(Left( + items.append(Top(Left(VBox( + Label(summary), ReplacePoint(Id('check_box_%s' % k), RadioButtonGroup(Id('entry_%s' % k), VBox( Left(RadioButton(Id(None), 'Not Configured', strcmp(disp, 'Not configured'))), Left(RadioButton(Id(True), 'Enabled', strcmp(disp, 'Enabled'))), Left(RadioButton(Id(False), 'Disabled', strcmp(disp, 'Disabled'))) ))) - ))) + )))) else: items.append(Top(Left( ReplacePoint(Id('check_box_%s' % k), CheckBox(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], bool(value[-1]['get']) if value[-1]['get'] else False)) ))) + elif strcmp(value[-1]['input']['type'], 'ListBox'): + disp = value[-1]['valstr'](value[-1]['get']) + items.append(Top(Left(VBox( + Label(summary), + ReplacePoint(Id('list_box_%s' % k), RadioButtonGroup(Id('entry_%s' % k), VBox( + Left(RadioButton(Id(None), 'Not Configured', strcmp(disp, 'Not configured'))), + Left(RadioButton(Id(True), 'Enabled', strcmp(disp, 'Enabled'))), + Left(RadioButton(Id(False), 'Disabled', strcmp(disp, 'Disabled'))), + Left(PushButton(Id('show'), 'Show...')) + ))) + )))) if reverse: items.reverse() items = tuple(items) @@ -216,7 +302,7 @@ conf = self.conn.parse(terms['file']) if conf is None: conf = terms['new']() - opts = terms['opts'](conf) + opts = terms['opts'](conf, label) header = tuple(terms['header']()) header = Header(*header) for key in opts: @@ -281,7 +367,11 @@ for category in categories: disp = fetch_attr(category, 'displayName', strings, presentations) my_ref = category.attrib['name'] - par_ref = category.find('parentCategory').attrib['ref'] + par = category.find('parentCategory') + if par is None: + par_ref = '' + else: + par_ref = par.attrib['ref'] if my_ref not in items.keys(): items[my_ref] = {} @@ -323,14 +413,18 @@ 'value' : { 'order' : 1, 'title' : key, - 'get' : get_admx_value(conf, reg_key, key), + 'get' : get_admx_value(conf, val_type, reg_key, key), 'set' : (lambda v : set_admx_value(conf, reg_key, key, v, val_type)), - 'valstr' : (lambda v : valstr(v) if get_admx_configured(conf, reg_key, key) else 'Not configured'), + 'valstr' : (lambda v : valstr(v) if get_admx_configured(conf, val_type, reg_key, key) else 'Not configured'), 'input' : _input, }, } ) - def policy_generator(conf): + def policy_generator(conf, parent): + def fetch_presentation(pid, typ): + pres = presentations.find('presentation[@id="%s"]' % pid) + if pres: + return pres.find(typ).text values = {} for policy in policies: if policy.find('parentCategory').attrib['ref'] != parent: @@ -340,7 +434,10 @@ values[disp] = {} val_type = None elements = policy.find('elements') - defined = get_admx_configured(conf, policy.attrib['key'], disp) + reg_key = policy.attrib['key'] + opts = None + elist = elements.find('list') + pid = policy.attrib['name'] if elements.find('text') is not None: val_type = 'TextEntry' val_str = (lambda v : v if v else '') @@ -350,12 +447,20 @@ elif elements.find('boolean') is not None: val_type = 'CheckBox' val_str = (lambda v : 'Disabled' if int(v) == 0 else 'Enabled') + elif elist is not None: + val_type = 'ListBox' + val_str = (lambda v : 'Disabled' if len(v) == 0 else 'Enabled') + reg_key = elist.attrib['key'] + opts = {} + opts['present'] = fetch_presentation(pid, 'listBox') + else: + raise NotImplementedError('Element of \'%s\' unknown' % disp) values[disp]['values'] = Policies[parent]['values']( - conf, policy.attrib['key'], disp, desc, val_str, val_type, + conf, reg_key, disp, desc, val_str, val_type, { 'type' : val_type, 'configurable' : True, - 'options' : None, + 'options' : opts, }, ) return values