Hello community,
here is the log from the commit of package yast2-ldap for openSUSE:Factory checked in at 2014-10-05 20:27:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-ldap (Old)
and /work/SRC/openSUSE:Factory/.yast2-ldap.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-ldap"
Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-ldap/yast2-ldap.changes 2014-08-08 10:10:06.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-ldap.new/yast2-ldap.changes 2014-10-05 20:27:29.000000000 +0200
@@ -1,0 +2,6 @@
+Thu Sep 25 10:21:52 UTC 2014 - varkoly@suse.com
+
+- bnc#897997 YaST2 User authentication not enumerating LDAP options
+- 3.1.13
+
+-------------------------------------------------------------------
Old:
----
yast2-ldap-3.1.12.tar.bz2
New:
----
yast2-ldap-3.1.13.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-ldap.spec ++++++
--- /var/tmp/diff_new_pack.b1FL5c/_old 2014-10-05 20:27:30.000000000 +0200
+++ /var/tmp/diff_new_pack.b1FL5c/_new 2014-10-05 20:27:30.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-ldap
-Version: 3.1.12
+Version: 3.1.13
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -59,6 +59,8 @@
%{yast_moduledir}/*
%{yast_clientdir}/*
%{yast_scrconfdir}/*.scr
+%dir %{yast_yncludedir}/ldap/
+%{yast_yncludedir}/ldap/*
%{yast_plugindir}/libpy2ag_ldap.so.*
%{yast_plugindir}/libpy2ag_ldap.so
%{yast_plugindir}/libpy2ag_ldap.la
++++++ yast2-ldap-3.1.12.tar.bz2 -> yast2-ldap-3.1.13.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/MAINTAINER new/yast2-ldap-3.1.13/MAINTAINER
--- old/yast2-ldap-3.1.12/MAINTAINER 2014-08-06 09:57:44.000000000 +0200
+++ new/yast2-ldap-3.1.13/MAINTAINER 2014-10-01 11:24:56.000000000 +0200
@@ -1 +1 @@
-Peter Varkoly
+Deprecated file. Use `osc maintainer yast2-ldap` instead.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/package/yast2-ldap.changes new/yast2-ldap-3.1.13/package/yast2-ldap.changes
--- old/yast2-ldap-3.1.12/package/yast2-ldap.changes 2014-08-06 09:57:44.000000000 +0200
+++ new/yast2-ldap-3.1.13/package/yast2-ldap.changes 2014-10-01 12:20:54.000000000 +0200
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Thu Sep 25 10:21:52 UTC 2014 - varkoly@suse.com
+
+- bnc#897997 YaST2 User authentication not enumerating LDAP options
+- 3.1.13
+
+-------------------------------------------------------------------
Tue Aug 5 13:02:04 UTC 2014 - varkoly@suse.com
- Set member_attribute to 'member'. We only use rfc2307bis.schema
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/package/yast2-ldap.spec new/yast2-ldap-3.1.13/package/yast2-ldap.spec
--- old/yast2-ldap-3.1.12/package/yast2-ldap.spec 2014-08-06 09:57:44.000000000 +0200
+++ new/yast2-ldap-3.1.13/package/yast2-ldap.spec 2014-10-01 12:20:54.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-ldap
-Version: 3.1.12
+Version: 3.1.13
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -52,6 +52,8 @@
%{yast_moduledir}/*
%{yast_clientdir}/*
%{yast_scrconfdir}/*.scr
+%dir %{yast_yncludedir}/ldap/
+%{yast_yncludedir}/ldap/*
%{yast_plugindir}/libpy2ag_ldap.so.*
%{yast_plugindir}/libpy2ag_ldap.so
%{yast_plugindir}/libpy2ag_ldap.la
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/src/Ldap.rb new/yast2-ldap-3.1.13/src/Ldap.rb
--- old/yast2-ldap-3.1.12/src/Ldap.rb 2014-08-06 09:57:44.000000000 +0200
+++ new/yast2-ldap-3.1.13/src/Ldap.rb 2014-10-01 12:20:54.000000000 +0200
@@ -1410,6 +1410,89 @@
deep_copy(@groups_dn)
end
+ # Check if given DN exist and if it points to some template
+ # @param [String] dn
+ # @return [Hash,nil] empty map if DN don't exist, template map if DN points
+ # to template object, nil if object with given DN is not template
+ def CheckTemplateDN(dn)
+ object = GetLDAPEntry(dn)
+ return object if object.nil? || object == {}
+ cls = Builtins.maplist(Ops.get_list(object, "objectClass", [])) do |c|
+ Builtins.tolower(c)
+ end
+ if Builtins.contains(cls, "suseobjecttemplate")
+ # exists as a template -> return object
+ object = ConvertDefaultValues(object)
+ Ops.set(object, "modified", "edited")
+ return AddMissingAttributes(object)
+ else
+ # error message
+ Popup.Error(
+ _(
+ "An object with the selected DN exists, but it is not a template object.\nSelect another one.\n"
+ )
+ )
+ return nil
+ end
+ end
+
+ # Save the edited map of configuration modules to global map
+ def CommitConfigModules(modules)
+ modules = deep_copy(modules)
+ Builtins.foreach(
+ Convert.convert(modules, :from => "map", :to => "map ")
+ ) do |dn, modmap|
+ if !Builtins.haskey(@config_modules, dn)
+ Ops.set(@config_modules, dn, Builtins.eval(modmap))
+ @ldap_modified = true
+ next
+ end
+ # 'val' can be list (most time), map (default_values), string
+ Builtins.foreach(
+ Convert.convert(modmap, :from => "map", :to => "map ")
+ ) do |attr, val|
+ if Ops.get(@config_modules, [dn, attr]) != val
+ Ops.set(@config_modules, [dn, attr], val)
+ if !Builtins.haskey(modmap, "modified")
+ Ops.set(@config_modules, [dn, "modified"], "edited")
+ end
+ @ldap_modified = true
+ Builtins.y2debug("modified value: %1", val)
+ end
+ end
+ end
+ true
+ end
+
+ # Save the edited map of templates to global map
+ def CommitTemplates(templs)
+ templs = deep_copy(templs)
+ Builtins.foreach(
+ Convert.convert(templs, :from => "map", :to => "map ")
+ ) do |dn, template|
+ if !Builtins.haskey(@templates, dn)
+ # dn changed
+ Ops.set(@templates, dn, Builtins.eval(template))
+ @ldap_modified = true
+ next
+ end
+ # 'val' can be list (most time), map (default_values), string
+ Builtins.foreach(
+ Convert.convert(template, :from => "map", :to => "map ")
+ ) do |attr, val|
+ if Ops.get(@templates, [dn, attr]) != val
+ Ops.set(@templates, [dn, attr], val)
+ if !Builtins.haskey(template, "modified")
+ Ops.set(@templates, [dn, "modified"], "edited")
+ end
+ @ldap_modified = true
+ Builtins.y2debug("modified value: %1", val)
+ end
+ end
+ end
+ true
+ end
+
# Writes map of objects to LDAP
# @param [Hash] objects map of objects to write. It is in the form:
# $[ DN: (map) attribute_values]
@@ -1848,6 +1931,9 @@
publish :function => :GetDefaultObjectClasses, :type => "list (map)"
publish :function => :ReadDN, :type => "list <string> (string, string)"
publish :function => :GetGroupsDN, :type => "list (string)"
+ publish :function => :CheckTemplateDN, :type => "map (string)"
+ publish :function => :CommitConfigModules, :type => "boolean (map)"
+ publish :function => :CommitTemplates, :type => "boolean (map)"
publish :function => :WriteToLDAP, :type => "map (map)"
publish :function => :WriteLDAP, :type => "boolean (map)"
publish :function => :WritePlusLine, :type => "boolean (boolean)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/src/Makefile.am new/yast2-ldap-3.1.13/src/Makefile.am
--- old/yast2-ldap-3.1.12/src/Makefile.am 2014-08-06 09:57:45.000000000 +0200
+++ new/yast2-ldap-3.1.13/src/Makefile.am 2014-10-01 12:20:54.000000000 +0200
@@ -26,10 +26,17 @@
module_DATA = \
LdapServerAccess.pm \
- LdapPopup.rb Ldap.rb
+ LdapPopup.rb \
+ Ldap.rb
client_DATA = \
- ldap_browser.rb
+ ldap_browser.rb \
+ ldap_config.rb
-EXTRA_DIST = $(module_DATA) $(client_DATA)
+yncludedir = @yncludedir@/ldap
+ynclude_DATA = \
+ routines.rb \
+ ui.rb
+
+EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/src/ldap_config.rb new/yast2-ldap-3.1.13/src/ldap_config.rb
--- old/yast2-ldap-3.1.12/src/ldap_config.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-ldap-3.1.13/src/ldap_config.rb 2014-10-01 12:20:54.000000000 +0200
@@ -0,0 +1,65 @@
+# encoding: utf-8
+
+# ------------------------------------------------------------------------------
+# Copyright (c) 2006-2012 Novell, Inc. All Rights Reserved.
+#
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of version 2 of the GNU General Public License as published by the
+# Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, contact Novell, Inc.
+#
+# To contact Novell about this file by physical or electronic mail, you may find
+# current contact information at www.novell.com.
+# ------------------------------------------------------------------------------
+
+# File: clients/ldap.ycp
+# Module: Configuration of LDAP client
+# Summary: Manage the configuration stored in LDAP directory
+# (e.g. user/group templates)
+# Authors: Jiri Suchomel
+#
+# $Id$
+module Yast
+ class LdapConfigClient < Client
+ def main
+ Yast.import "UI"
+ Yast.import "Ldap"
+ Yast.import "Wizard"
+
+ Yast.include self, "ldap/ui.rb"
+
+ @param = ""
+ # Check arguments
+ if Ops.greater_than(Builtins.size(WFM.Args), 0) &&
+ Ops.is_string?(WFM.Args(0))
+ @param = Convert.to_string(WFM.Args(0))
+ end
+ Builtins.y2debug("param=%1", @param)
+
+ @ret = LDAPReadDialog()
+ return deep_copy(@ret) if @ret != :next
+
+ Wizard.CreateDialog
+ Wizard.SetDesktopTitleAndIcon("ldap")
+
+ @ret = ModuleConfigurationDialog()
+
+ if @ret == :next && Ldap.ldap_modified
+ Ldap.WriteLDAP(Ldap.templates) if Ldap.WriteLDAP(Ldap.config_modules)
+ end
+
+ Wizard.CloseDialog
+
+ deep_copy(@ret)
+ end
+ end
+end
+
+Yast::LdapConfigClient.new.main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/src/routines.rb new/yast2-ldap-3.1.13/src/routines.rb
--- old/yast2-ldap-3.1.12/src/routines.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-ldap-3.1.13/src/routines.rb 2014-10-01 12:20:54.000000000 +0200
@@ -0,0 +1,81 @@
+# encoding: utf-8
+
+# ------------------------------------------------------------------------------
+# Copyright (c) 2006-2012 Novell, Inc. All Rights Reserved.
+#
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of version 2 of the GNU General Public License as published by the
+# Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, contact Novell, Inc.
+#
+# To contact Novell about this file by physical or electronic mail, you may find
+# current contact information at www.novell.com.
+# ------------------------------------------------------------------------------
+
+# File: include/ldap/routines.ycp
+# Package: Configuration of LDAP
+# Summary: Helper routines for string manupulations
+# Authors: Jiri Suchomel
+#
+# $Id$
+#
+module Yast
+ module LdapRoutinesInclude
+ def initialize_ldap_routines(include_target)
+ textdomain "ldap-client"
+
+ Yast.import "Ldap"
+ end
+
+ # Get RDN (relative distinguished name) from dn
+ def get_rdn(dn)
+ dn_list = Builtins.splitstring(dn, ",")
+ Ops.get_string(dn_list, 0, dn)
+ end
+
+ # Get first value from dn (don't have to be "cn")
+ def get_cn(dn)
+ rdn = get_rdn(dn)
+ Builtins.issubstring(rdn, "=") ?
+ Builtins.substring(rdn, Ops.add(Builtins.search(rdn, "="), 1)) :
+ rdn
+ end
+
+ # Create DN from cn by adding base config DN
+ # (Can't work in general cases!)
+ def get_dn(cn)
+ Builtins.sformat("cn=%1,%2", cn, Ldap.base_config_dn)
+ end
+
+ # Create new DN from DN by changing leading cn value
+ # (Can't work in general cases!)
+ def get_new_dn(cn, dn)
+ Builtins.tolower(
+ Builtins.sformat(
+ "cn=%1%2",
+ cn,
+ Builtins.issubstring(dn, ",") ?
+ Builtins.substring(dn, Builtins.search(dn, ",")) :
+ ""
+ )
+ )
+ end
+
+ # Get string value of attribute from map.
+ # (Generaly, it is supposed to be list or string.)
+ def get_string(object, attr)
+ object = deep_copy(object)
+ if Ops.is_list?(Ops.get(object, attr))
+ return Ops.get_string(object, [attr, 0], "")
+ end
+ Ops.get_string(object, attr, "")
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-ldap-3.1.12/src/ui.rb new/yast2-ldap-3.1.13/src/ui.rb
--- old/yast2-ldap-3.1.12/src/ui.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-ldap-3.1.13/src/ui.rb 2014-10-01 12:20:54.000000000 +0200
@@ -0,0 +1,815 @@
+# encoding: utf-8
+
+# ------------------------------------------------------------------------------
+# Copyright (c) 2006-2012 Novell, Inc. All Rights Reserved.
+#
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of version 2 of the GNU General Public License as published by the
+# Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, contact Novell, Inc.
+#
+# To contact Novell about this file by physical or electronic mail, you may find
+# current contact information at www.novell.com.
+# ------------------------------------------------------------------------------
+
+# File: include/ldap/ui.ycp
+# Package: Configuration of LDAP
+# Summary: User interface functions.
+# Authors: Thorsten Kukuk
+# Anas Nashif
+#
+# $Id$
+#
+# All user interface functions.
+module Yast
+ module LdapUiInclude
+ def initialize_ldap_ui(include_target)
+ Yast.import "UI"
+ textdomain "ldap-client"
+
+ Yast.import "Address"
+ Yast.import "Autologin"
+ Yast.import "Directory"
+ Yast.import "FileUtils"
+ Yast.import "Label"
+ Yast.import "Ldap"
+ Yast.import "LdapPopup"
+ Yast.import "Message"
+ Yast.import "Mode"
+ Yast.import "Package"
+ Yast.import "Pam"
+ Yast.import "Popup"
+ Yast.import "Report"
+ Yast.import "Service"
+ Yast.import "SLPAPI"
+ Yast.import "Stage"
+ Yast.import "Wizard"
+
+ Yast.include include_target, "ldap/routines.rb"
+ end
+
+ def Modified
+ Ldap.modified || Ldap.ldap_modified
+ end
+
+ # The dialog that appears when the [Abort] button is pressed.
+ # @return `abort if user really wants to abort, `back otherwise
+ def ReallyAbort
+ ret = Modified() || Stage.cont ? Popup.ReallyAbort(true) : true
+
+ if ret
+ return :abort
+ else
+ return :back
+ end
+ end
+
+ # Read settings dialog
+ # @return `abort if aborted and `next otherwise
+ def ReadDialog
+ ret = Ldap.Read
+ ret ? :next : :abort
+ end
+
+ # Write settings dialog
+ # @return `next
+ def WriteDialog
+ # popup text
+ abort = lambda do
+ if UI.PollInput == :abort &&
+ # popup text
+ Popup.YesNo(_("Really abort the writing process?"))
+ next true
+ end
+ false
+ end
+
+ if Modified()
+ # help text
+ Wizard.RestoreHelp(_("Writing LDAP Client Settings"))
+ return Ldap.Write(abort)
+ end
+ :next
+ end
+
+ # Initialize connection to LDAP server, bind and read the settings.
+ # Everything is done before entering the Module Configuration Dialog.
+ def LDAPReadDialog
+ msg = ""
+ read_now = false
+
+ if !Ldap.bound || Modified()
+ if !Ldap.bound || Ldap.modified
+ # re-init/re-bind only when server information was changed (#39908)
+ if !Ldap.bound || Ldap.old_server != Ldap.server || Ldap.BaseDNChanged
+ msg = Ldap.LDAPInitWithTLSCheck({})
+ if msg != ""
+ Ldap.LDAPErrorMessage("init", msg)
+ return :back
+ end
+ end
+
+ if !Ldap.bound || Ldap.old_server != Ldap.server
+ # Ldap::bind_pass might exist from server proposal...
+ if Stage.cont && Ldap.bind_pass != nil
+ msg = Ldap.LDAPBind(Ldap.bind_pass)
+ if msg != ""
+ Ldap.LDAPErrorMessage("bind", msg)
+ Ldap.bind_pass = Ldap.LDAPAskAndBind(true)
+ end
+ else
+ Ldap.bind_pass = Ldap.LDAPAskAndBind(true)
+ end
+ return :back if Ldap.bind_pass == nil
+
+ read_now = true
+
+ msg = Ldap.InitSchema
+ Ldap.LDAPErrorMessage("schema", msg) if msg != ""
+ end
+ end
+ return :back if !Ldap.CheckBaseConfig(Ldap.base_config_dn)
+ if read_now || Ldap.modified && !Ldap.ldap_modified ||
+ Ldap.ldap_modified &&
+ Popup.AnyQuestion(
+ Popup.NoHeadline,
+ # yes/no popup
+ _(
+ "If you reread settings from the server,\nall changes will be lost. Really reread?\n"
+ ),
+ Label.YesButton,
+ Label.NoButton,
+ :focus_no
+ )
+ msg = Ldap.ReadConfigModules
+ Ldap.LDAPErrorMessage("read", msg) if msg != ""
+
+ msg = Ldap.ReadTemplates
+ Ldap.LDAPErrorMessage("read", msg) if msg != ""
+
+ Ldap.ldap_modified = false
+ end
+ Ldap.bound = true
+ end
+ :next
+ end
+
+ # Dialog for configuration one object template
+ def TemplateConfigurationDialog(templ)
+ templ = deep_copy(templ)
+ # help text 1/3
+ help_text = _(
+ "<p>Configure the template used for creating \nnew objects (like users or groups).</p>\n"
+ ) +
+ # help text 2/3
+ _(
+ "<p>Edit the template attribute values with <b>Edit</b>.\nChanging the <b>cn</b> value renames the template.</p>\n"
+ ) +
+ # help text 3/3
+ _(
+ "<p>The second table contains a list of <b>default values</b> used\n" +
+ "for new objects. Modify the list by adding new values, editing or\n" +
+ "removing current ones.</p>\n"
+ )
+
+ template_dn = Ldap.current_template_dn
+
+ table_items = []
+ template = Convert.convert(
+ Builtins.eval(templ),
+ :from => "map",
+ :to => "map "
+ )
+
+ # helper function converting list value to string
+ to_table = lambda do |attr, val|
+ val = deep_copy(val)
+ if Ldap.SingleValued(attr) || attr == "cn"
+ return Ops.get(val, 0, "")
+ elsif Builtins.contains(
+ ["susesecondarygroup", "susedefaulttemplate"],
+ Builtins.tolower(attr)
+ )
+ return Builtins.mergestring(val, " ")
+ else
+ return Builtins.mergestring(val, ",")
+ end
+ end
+
+ Builtins.foreach(template) do |attr, value|
+ val = deep_copy(value)
+ # do not show internal attributes
+ if Builtins.contains(
+ [
+ "susedefaultvalue",
+ "default_values",
+ "objectclass",
+ "modified",
+ "old_dn"
+ ],
+ Builtins.tolower(attr)
+ )
+ next
+ end
+ if Ops.is_list?(value)
+ val = to_table.call(
+ attr,
+ Convert.convert(val, :from => "any", :to => "list <string>")
+ )
+ end
+ table_items = Builtins.add(table_items, Item(Id(attr), attr, val))
+ end
+
+ default_items = []
+ default_values = Ops.get_map(template, "default_values", {})
+ Builtins.foreach(default_values) do |attr, value|
+ default_items = Builtins.add(default_items, Item(Id(attr), attr, value))
+ end
+
+ contents = HBox(
+ HSpacing(1.5),
+ VBox(
+ VSpacing(0.5),
+ Table(
+ Id(:table),
+ Opt(:notify),
+ Header(
+ # table header 1/2
+ _("Attribute"),
+ # table header 2/2
+ _("Value")
+ ),
+ table_items
+ ),
+ HBox(PushButton(Id(:edit), Label.EditButton), HStretch()),
+ # label (table folows)
+ Left(Label(_("Default Values for New Objects"))),
+ Table(
+ Id(:defaults),
+ Opt(:notify),
+ Header(
+ # table header 1/2
+ _("Attribute of Object"),
+ # table header 2/2
+ _("Default Value")
+ ),
+ default_items
+ ),
+ HBox(
+ # button label (with non-default shortcut)
+ PushButton(Id(:add_dfl), Opt(:key_F3), _("A&dd")),
+ # button label
+ PushButton(Id(:edit_dfl), Opt(:key_F4), _("&Edit")),
+ PushButton(Id(:delete_dfl), Opt(:key_F5), Label.DeleteButton),
+ HStretch()
+ ),
+ VSpacing(0.5)
+ ),
+ HSpacing(1.5)
+ )
+
+ Wizard.OpenNextBackDialog
+ # dialog label
+ Wizard.SetContentsButtons(
+ _("Object Template Configuration"),
+ contents,
+ help_text,
+ Label.CancelButton,
+ Label.OKButton
+ )
+ Wizard.HideAbortButton
+
+ UI.SetFocus(Id(:table)) if Ops.greater_than(Builtins.size(table_items), 0)
+ UI.ChangeWidget(Id(:edit_dfl), :Enabled, default_items != [])
+ UI.ChangeWidget(Id(:delete_dfl), :Enabled, default_items != [])
+
+ result = nil
+ while true
+ result = UI.UserInput
+ attr = Convert.to_string(UI.QueryWidget(Id(:table), :CurrentItem))
+
+ # edit attribute
+ if result == :edit || result == :table
+ next if attr == nil
+ value = Ops.get_list(template, attr, [])
+ offer = []
+ conflicts = []
+ if Builtins.tolower(attr) == "susesecondarygroup"
+ offer = Ldap.GetGroupsDN(Ldap.GetBaseDN)
+ end
+ if Builtins.tolower(attr) == "susenamingattribute"
+ classes = Ldap.GetDefaultObjectClasses(template)
+ offer = Ldap.GetObjectAttributes(classes)
+ end
+ if attr == "cn"
+ base = Builtins.issubstring(template_dn, ",") ?
+ Builtins.substring(
+ template_dn,
+ Ops.add(Builtins.search(template_dn, ","), 1)
+ ) :
+ ""
+ Builtins.foreach(Ldap.ReadDN(base, "")) do |dn|
+ if Builtins.substring(dn, 0, 3) == "cn="
+ conflicts = Builtins.add(conflicts, get_cn(dn))
+ end
+ end
+ end
+ value = LdapPopup.EditAttribute(
+ {
+ "attr" => attr,
+ "value" => value,
+ "conflicts" => conflicts,
+ "single" => Ldap.SingleValued(attr) || attr == "cn",
+ "offer" => offer,
+ "browse" => Builtins.tolower(attr) == "susesecondarygroup"
+ }
+ )
+
+ next if value == Ops.get_list(template, attr, [])
+ UI.ChangeWidget(
+ Id(:table),
+ term(:Item, attr, 1),
+ to_table.call(attr, value)
+ )
+ Ops.set(template, attr, value)
+ end
+ # add default value
+ if result == :add_dfl
+ conflicts = Builtins.maplist(default_values) { |attr3, val| attr3 }
+ classes = Ldap.GetDefaultObjectClasses(template)
+ available = Ldap.GetObjectAttributes(classes)
+ # filter out objectclass
+ dfl = LdapPopup.AddDefaultValue(
+ Builtins.sort(available),
+ Builtins.add(conflicts, "objectClass")
+ )
+ next if Ops.get_string(dfl, "value", "") == ""
+ attr2 = Ops.get_string(dfl, "attr", "")
+ Ops.set(default_values, attr2, Ops.get_string(dfl, "value", ""))
+ default_items = Builtins.add(
+ default_items,
+ Item(Id(attr2), attr2, Ops.get_string(dfl, "value", ""))
+ )
+ UI.ChangeWidget(Id(:defaults), :Items, default_items)
+ UI.ChangeWidget(Id(:edit_dfl), :Enabled, default_items != [])
+ UI.ChangeWidget(Id(:delete_dfl), :Enabled, default_items != [])
+ end
+ # edit default value
+ if result == :edit_dfl || result == :defaults
+ attr = Convert.to_string(UI.QueryWidget(Id(:defaults), :CurrentItem))
+ next if attr == nil
+ value = Ops.get(default_values, attr, "")
+ l_value = LdapPopup.EditAttribute(
+ { "attr" => attr, "value" => [value], "single" => true }
+ )
+ next if Ops.get_string(l_value, 0, "") == value
+ value = Ops.get_string(l_value, 0, "")
+ UI.ChangeWidget(Id(:defaults), term(:Item, attr, 1), value)
+ Ops.set(default_values, attr, value)
+ end
+ # delete default value
+ if result == :delete_dfl
+ attr = Convert.to_string(UI.QueryWidget(Id(:defaults), :CurrentItem))
+ next if attr == nil
+ # yes/no popup, %1 is name
+ if !Popup.YesNo(
+ Builtins.sformat(
+ _("Really delete default attribute \"%1\"?"),
+ attr
+ )
+ )
+ next
+ end
+ default_values = Builtins.remove(default_values, attr)
+ default_items = Builtins.filter(default_items) do |it|
+ Ops.get_string(it, 1, "") != attr
+ end
+ UI.ChangeWidget(Id(:defaults), :Items, default_items)
+ UI.ChangeWidget(Id(:edit_dfl), :Enabled, default_items != [])
+ UI.ChangeWidget(Id(:delete_dfl), :Enabled, default_items != [])
+ end
+ if Ops.is_symbol?(result) &&
+ Builtins.contains(
+ [:back, :cancel, :abort],
+ Convert.to_symbol(result)
+ )
+ break
+ end
+ if result == :next
+ cont = false
+
+ # check the template required attributes...
+ Builtins.foreach(Ops.get_list(template, "objectClass", [])) do |oc|
+ next if cont
+ Builtins.foreach(Ldap.GetRequiredAttributes(oc)) do |attr2|
+ val = Ops.get(template, attr2)
+ if !cont && val == nil || val == [] || val == ""
+ #error popup, %1 is attribute name
+ Popup.Error(
+ Builtins.sformat(
+ _("The \"%1\" attribute is mandatory.\nEnter a value."),
+ attr2
+ )
+ )
+ UI.SetFocus(Id(:table))
+ cont = true
+ end
+ end
+ end
+ next if cont
+ Ops.set(template, "default_values", default_values)
+ break
+ end
+ end
+ Wizard.CloseDialog
+ deep_copy(template)
+ end
+
+ # Dialog for configuration of one "configuration module"
+ def ModuleConfigurationDialog
+ # helptext 1/4
+ help_text = _(
+ "<p>Manage the configuration stored in the LDAP directory.</p>"
+ ) +
+ # helptext 2/4
+ _(
+ "<p>Each configuration set is called a \"configuration module.\" If there\n" +
+ "is no configuration module in the provided location (base configuration),\n" +
+ "create one with <b>New</b>. Delete the current module\n" +
+ "using <b>Delete</b>.</p>\n"
+ ) +
+ # helptext 3/4
+ _(
+ "<p>Edit the values of attributes in the table with <b>Edit</b>.\n" +
+ "Some values have special meanings, for example, changing the <b>cn</b> value renames the\n" +
+ "current module.</p>\n"
+ ) +
+ # helptext 4/4
+ _(
+ "<p>To configure the default template of the current module,\n" +
+ "click <b>Configure Template</b>.\n" +
+ "</p>\n"
+ )
+
+ current_dn = Ldap.current_module_dn
+ modules_attrs_items = {} # map of list (table items), index is cn
+ modules = Convert.convert(
+ Ldap.GetConfigModules,
+ :from => "map",
+ :to => "map >"
+ )
+ templates = Convert.convert(
+ Ldap.GetTemplates,
+ :from => "map",
+ :to => "map >"
+ )
+ names = []
+ templates_dns = Builtins.maplist(templates) { |dn, t| dn }
+
+ # Helper for creating table items in ModuleConfiguration Dialog
+ create_attrs_items = lambda do |cn|
+ attrs_items = []
+ dn = get_dn(cn)
+ dn = Builtins.tolower(dn) if !Builtins.haskey(modules, dn)
+ Builtins.foreach(Ops.get(modules, dn, {})) do |attr, value|
+ val = deep_copy(value)
+ if Builtins.contains(
+ ["objectclass", "modified", "old_dn"],
+ Builtins.tolower(attr)
+ )
+ next
+ end
+ if Ops.is_list?(value)
+ lvalue = Convert.to_list(value)
+ if Ldap.SingleValued(attr) || attr == "cn"
+ val = Ops.get_string(lvalue, 0, "")
+ else
+ val = Builtins.mergestring(
+ Convert.convert(value, :from => "any", :to => "list <string>"),
+ ","
+ )
+ end
+ end
+ attrs_items = Builtins.add(attrs_items, Item(Id(attr), attr, val))
+ end
+
+ deep_copy(attrs_items)
+ end
+
+ Builtins.foreach(modules) do |dn, mod|
+ cn = get_string(mod, "cn")
+ next if cn == ""
+ names = Builtins.add(names, cn)
+ # attributes for table
+ Ops.set(modules_attrs_items, cn, create_attrs_items.call(cn))
+ current_dn = dn if current_dn == ""
+ end
+ current_cn = Ops.get_string(modules, [current_dn, "cn", 0]) do
+ get_cn(current_dn)
+ end
+
+ # Helper for updating widgets in ModuleConfiguration Dialog
+ replace_module_names = lambda do
+ modules_items = [] # list of module names
+ Builtins.foreach(names) do |cn|
+ if Builtins.tolower(cn) == Builtins.tolower(current_cn)
+ modules_items = Builtins.add(modules_items, Item(Id(cn), cn, true))
+ else
+ modules_items = Builtins.add(modules_items, Item(Id(cn), cn))
+ end
+ end
+ UI.ReplaceWidget(
+ Id(:rp_modnames),
+ Left(
+ ComboBox(
+ Id(:modules),
+ Opt(:notify),
+ # combobox label
+ _("Configuration &Module"),
+ modules_items
+ )
+ )
+ )
+ ena = names != []
+ UI.ChangeWidget(Id(:delete), :Enabled, ena)
+ UI.ChangeWidget(Id(:edit), :Enabled, ena)
+ UI.ChangeWidget(Id(:modules), :Enabled, ena)
+
+ nil
+ end
+
+ # Helper for updating widgets in ModuleConfiguration Dialog
+ replace_templates_items = lambda do
+ items = Builtins.maplist(
+ Ops.get_list(modules, [current_dn, "suseDefaultTemplate"], [])
+ ) { |dn| Item(Id(dn), dn) }
+ UI.ReplaceWidget(
+ Id(:rp_templs),
+ PushButton(
+ Id(:templ_pb),
+ Opt(:key_F7),
+ # button label
+ _("C&onfigure Template")
+ )
+ )
+ UI.ChangeWidget(Id(:templ_pb), :Enabled, items != [])
+
+ nil
+ end
+
+ contents = HBox(
+ HSpacing(1.5),
+ VBox(
+ VSpacing(0.5),
+ HBox(
+ ReplacePoint(Id(:rp_modnames), Empty())
+ ),
+ VSpacing(0.5),
+ Table(
+ Id(:table),
+ Opt(:notify),
+ Header(
+ # table header 1/2
+ _("Attribute"),
+ # table header 2/2
+ _("Value")
+ ),
+ Ops.get_list(modules_attrs_items, current_cn, [])
+ ),
+ HBox(
+ PushButton(Id(:edit), Opt(:key_F4), Label.EditButton),
+ HStretch(),
+ ReplacePoint(Id(:rp_templs), Empty())
+ ),
+ VSpacing(0.5)
+ ),
+ HSpacing(1.5)
+ )
+
+ # dialog label
+ Wizard.SetContentsButtons(
+ _("Module Configuration"),
+ contents,
+ help_text,
+ Label.CancelButton,
+ Label.OKButton
+ )
+ Wizard.HideAbortButton
+
+ if Ops.greater_than(
+ Builtins.size(Ops.get_list(modules_attrs_items, current_cn, [])),
+ 0
+ )
+ UI.SetFocus(Id(:table))
+ end
+ replace_templates_items.call
+ replace_module_names.call
+
+ # result could be symbol or string
+ result = nil
+ while true
+ result = UI.UserInput
+ attr = Convert.to_string(UI.QueryWidget(Id(:table), :CurrentItem))
+
+ # check the correctness of entry
+ if Builtins.contains(
+ Ops.get_list(modules, [current_dn, "suseDefaultTemplate"], []),
+ result
+ ) ||
+ result == :next ||
+ result == :modules
+ Builtins.foreach(
+ Ops.get_list(modules, [current_dn, "objectClass"], [])
+ ) { |oc| Builtins.foreach(Ldap.GetRequiredAttributes(oc)) do |attr2|
+ val = Ops.get(modules, [current_dn, attr2])
+ if val == nil || val == [] || val == ""
+ #error popup, %1 is attribute name
+ Popup.Error(
+ Builtins.sformat(
+ _("The \"%1\" attribute is mandatory.\nEnter a value."),
+ attr2
+ )
+ )
+ UI.SetFocus(Id(:table))
+ result = :notnext
+ next
+ end
+ end }
+ end
+ # change the focus to new module
+ if result == :modules
+ current_cn = Convert.to_string(UI.QueryWidget(Id(:modules), :Value))
+ current_dn = get_dn(current_cn)
+ if !Builtins.haskey(modules, current_dn)
+ current_dn = Builtins.tolower(current_dn)
+ end
+ UI.ChangeWidget(
+ Id(:table),
+ :Items,
+ Ops.get_list(modules_attrs_items, current_cn, [])
+ )
+ replace_templates_items.call
+ end
+
+ # module attribute modification
+ if result == :edit || result == :table
+ next if attr == nil
+ value = Ops.get_list(modules, [current_dn, attr], [])
+ offer = []
+ conflicts = []
+ conflicts = deep_copy(names) if attr == "cn"
+ if Builtins.tolower(attr) == "susedefaulttemplate"
+ offer = deep_copy(templates_dns)
+ elsif Builtins.tolower(attr) == "susepasswordhash"
+ offer = deep_copy(Ldap.hash_schemas)
+ end
+
+ value = LdapPopup.EditAttribute(
+ {
+ "attr" => attr,
+ "value" => value,
+ "conflicts" => conflicts,
+ "single" => Ldap.SingleValued(attr) || attr == "cn",
+ "offer" => offer,
+ "browse" =>
+ # TODO function, that checks if value should be DN
+ Builtins.tolower(attr) == "susedefaultbase" ||
+ Builtins.tolower(attr) == "susedefaulttemplate"
+ }
+ )
+
+ if value == Ops.get_list(modules, [current_dn, attr], []) #nothing was changed
+ next
+ end
+ Ops.set(modules, [current_dn, attr], value)
+ Ops.set(
+ modules_attrs_items,
+ current_cn,
+ create_attrs_items.call(current_cn)
+ )
+ UI.ChangeWidget(
+ Id(:table),
+ :Items,
+ Ops.get_list(modules_attrs_items, current_cn, [])
+ )
+ UI.ChangeWidget(Id(:table), :CurrentItem, attr)
+ if attr == "cn" && value != []
+ cn = Ops.get(value, 0, current_cn)
+ Ops.set(
+ modules_attrs_items,
+ cn,
+ Ops.get_list(modules_attrs_items, current_cn, [])
+ )
+ modules_attrs_items = Builtins.remove(
+ modules_attrs_items,
+ current_cn
+ )
+ if Ops.get_string(modules, [current_dn, "modified"], "") != "added" &&
+ Ops.get_string(modules, [current_dn, "modified"], "") != "renamed"
+ Ops.set(modules, [current_dn, "modified"], "renamed")
+ Ops.set(modules, [current_dn, "old_dn"], current_dn)
+ end
+ Ops.set(modules, get_dn(cn), Ops.get(modules, current_dn, {}))
+ if Builtins.tolower(get_dn(cn)) != Builtins.tolower(current_dn)
+ modules = Builtins.remove(modules, current_dn)
+ end
+ names = Builtins.filter(names) { |n| n != current_cn }
+ names = Builtins.add(names, cn)
+ current_cn = cn
+ current_dn = get_dn(cn)
+ replace_module_names.call
+ end
+ if Builtins.tolower(attr) == "susedefaulttemplate"
+ replace_templates_items.call
+ end
+ end
+ # configure template
+ if result == :templ_pb
+ template_dn = Ops.get_string(
+ modules,
+ [current_dn, "suseDefaultTemplate", 0],
+ ""
+ )
+ Ldap.current_template_dn = template_dn
+ template = Builtins.eval(Ops.get(templates, template_dn, {}))
+ # template not loaded, check DN:
+ if template == {}
+ template = Ldap.CheckTemplateDN(template_dn)
+ if template == nil
+ next
+ elsif template == {}
+ next if !Ldap.ParentExists(template_dn)
+ template = Ldap.CreateTemplate(
+ get_cn(template_dn),
+ Ops.get_list(modules, [current_dn, "objectClass"], [])
+ )
+ end
+ templates_dns = Builtins.add(templates_dns, template_dn)
+ end
+ Ops.set(templates, template_dn, TemplateConfigurationDialog(template))
+ # check for template renaming
+ if Ops.get_list(templates, [template_dn, "cn"], []) !=
+ Ops.get_list(template, "cn", [])
+ cn = get_string(Ops.get(templates, template_dn, {}), "cn")
+ new_dn = get_new_dn(cn, template_dn)
+
+ Ops.set(templates, new_dn, Ops.get(templates, template_dn, {}))
+ if new_dn != template_dn
+ templates = Builtins.remove(templates, template_dn)
+ end
+ if Ops.get_string(templates, [new_dn, "modified"], "") != "added"
+ Ops.set(templates, [new_dn, "modified"], "renamed")
+ Ops.set(templates, [new_dn, "old_dn"], template_dn)
+ end
+ templates_dns = Builtins.filter(templates_dns) do |dn|
+ dn != template_dn
+ end
+ templates_dns = Builtins.add(templates_dns, new_dn)
+ # update list of templates
+ Ops.set(
+ modules,
+ [current_dn, "suseDefaultTemplate"],
+ Builtins.maplist(
+ Ops.get_list(modules, [current_dn, "suseDefaultTemplate"], [])
+ ) do |dn|
+ next new_dn if dn == template_dn
+ dn
+ end
+ )
+ Ops.set(
+ modules_attrs_items,
+ current_cn,
+ create_attrs_items.call(current_cn)
+ )
+ UI.ChangeWidget(
+ Id(:table),
+ :Items,
+ Ops.get_list(modules_attrs_items, current_cn, [])
+ )
+ replace_templates_items.call
+ end
+ UI.SetFocus(Id(:table))
+ end
+ if result == :next
+ Ldap.current_module_dn = current_dn
+ # save the edited values to global map...
+ Ldap.CommitConfigModules(modules)
+ # commit templates here!
+ Ldap.CommitTemplates(templates)
+ break
+ end
+ result = :not_next if result == :cancel && ReallyAbort() != :abort
+ break if result == :back || result == :cancel
+ end
+
+ Convert.to_symbol(result)
+ end
+ end
+end
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org