On 03/15/2013 11:47 PM, Endi Sukma Dewata wrote:
On 3/7/2013 7:37 AM, Petr Vobornik wrote:
Ideally it should be generic enough to combine any widgets. This might
be a common scenario somewhere else:
Something: ( ) Option 1
( ) Option 2
(o) Other: [something else ]
This design has a flaw:
https://fedorahosted.org/freeipa/ticket/3404#comment:5
I think this one makes the most sense to me:
PAC Types: ( ) Inherited setting: ... <inherited values> ...
(o) Override inherited setting
[ ] MS-PAC
[ ] PAD
It looks like the NONE option is identical to not using the inherited
values but also not selecting any new values, so we don't actually need
a separate radio button for NONE because it can be represented by the
above UI without redundancy. We just need better labels to explain the
radio buttons. Maybe someone can come up with better labels than these.
I implemented following design:
https://fedorahosted.org/freeipa/ticket/3404#comment:7
It works but I can't imagine how it would look if we have more than two
PAC types. I don't think we want to list every possible combinations.
The above design is more future proof.
You are right.
Patch attached (255-1).
I have a dilemma. I practically implemented the previous design (and
then I've found the flaw..). Patches attached as wip-fre... I wonder if
we can use it somehow or we should ditch it.
Reimplemented ^^ to match your proposal. Attaching as patches with new
numbers (271,272) as they don't have much common with the original patch.
--
Petr Vobornik
From 5c1b323629fd97014aae1d5c0e6b991aff59003d Mon Sep 17 00:00:00 2001
From: Petr Vobornik <[email protected]>
Date: Fri, 22 Mar 2013 17:53:04 +0100
Subject: [PATCH] Nestable checkbox/radio widget
New component: option_widget_base. It's not a regular widget but it share some of its characteristics. It should extend regular widget or it can be nested in itself alone.
checkbox_widget, checkboxes_widget, radio_widget were modified to use it.
Built as a prerequisite for:
https://fedorahosted.org/freeipa/ticket/3404
---
install/ui/ipa.css | 15 +
install/ui/src/freeipa/aci.js | 15 +-
install/ui/src/freeipa/rule.js | 3 +-
install/ui/src/freeipa/widget.js | 646 ++++++++++++++++++++++++++-------------
4 files changed, 463 insertions(+), 216 deletions(-)
diff --git a/install/ui/ipa.css b/install/ui/ipa.css
index 71cad4206fd0780d6578846827922ec4edb56458..3e443d54ecef523c7a47cfaec91bedd9bc3006e8 100644
--- a/install/ui/ipa.css
+++ b/install/ui/ipa.css
@@ -1294,6 +1294,21 @@ table.scrollable tbody {
width: 400px;
}
+.option_widget {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+.option_widget.nested {
+ padding-left: 40px;
+}
+
+.option_widget.inline,
+.option_widget.inline > li {
+ display: inline;
+}
+
.combobox-widget-input {
display: inline-block;
position: relative;
diff --git a/install/ui/src/freeipa/aci.js b/install/ui/src/freeipa/aci.js
index 383848ec635985a9582418ef4a1bb2a26dac9c36..b6825d136333169fe46b43512401f84eb5d05e85 100644
--- a/install/ui/src/freeipa/aci.js
+++ b/install/ui/src/freeipa/aci.js
@@ -477,7 +477,7 @@ IPA.attributes_widget = function(spec) {
'class': 'aci-attribute-table-container'
}).appendTo(container);
- that.table = $('<table/>', {
+ that.$node = that.table = $('<table/>', {
id:id,
'class':'search-table aci-attribute-table scrollable'
}).
@@ -520,9 +520,12 @@ IPA.attributes_widget = function(spec) {
var tr = $('<tr/>').appendTo(tbody);
var td = $('<td/>').appendTo(tr);
+ var name = that.get_input_name();
+ var id = that.option_next_id + name;
td.append($('<input/>',{
+ id: id,
type: 'checkbox',
- name: that.name,
+ name: name,
value: value,
'class': 'aci-attribute',
change: function() {
@@ -531,8 +534,10 @@ IPA.attributes_widget = function(spec) {
}));
td = $('<td/>').appendTo(tr);
td.append($('<label/>',{
- text: value
+ text: value,
+ 'for': id
}));
+ that.new_option_id();
}
};
@@ -553,7 +558,7 @@ IPA.attributes_widget = function(spec) {
that.populate(that.object_type);
that.append();
- that.checkboxes_update(values);
+ that.owb_update(values);
};
that.populate = function(object_type) {
@@ -567,6 +572,7 @@ IPA.attributes_widget = function(spec) {
var aciattrs = metadata.aciattrs;
+ that.options = that.prepare_options(aciattrs);
that.create_options(aciattrs);
};
@@ -585,6 +591,7 @@ IPA.attributes_widget = function(spec) {
}
if (unmatched.length > 0 && !that.skip_unmatched) {
+ that.options.push.apply(that.options, that.prepare_options(unmatched));
that.create_options(unmatched);
}
};
diff --git a/install/ui/src/freeipa/rule.js b/install/ui/src/freeipa/rule.js
index 888fd4508e25fc8f7913042c9da5580c73ccf623..436e934cab80c07d66f747660299e59e7a9a2ce9 100644
--- a/install/ui/src/freeipa/rule.js
+++ b/install/ui/src/freeipa/rule.js
@@ -43,7 +43,8 @@ IPA.rule_details_widget = function(spec) {
that.enable_radio.value_changed.attach(that.on_enable_radio_changed);
};
- that.on_enable_radio_changed = function(value) {
+ that.on_enable_radio_changed = function() {
+ var value = that.enable_radio.save();
if(value.length > 0) {
var enabled = ('' === value[0]);
for (var i=0; i<that.tables.length; i++) {
diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
index 5ce767e7e5f1f2b0310ae5da55893533c5b4e380..44b8611a3ce7a6f02d1fd259d9a59b03a80dc733 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -21,7 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-define(['./ipa', './jquery'], function(IPA, $) {
+define(['dojo/_base/array', './ipa', './jquery'], function(array, IPA, $) {
IPA.checkbox_column_width = 22;
IPA.required_indicator = '*';
@@ -616,237 +616,461 @@ IPA.multivalued_widget = function(spec) {
return that;
};
+/**
+ * Widget base for checkboxes and radios. Doesn't handle dirty state's but
+ * its supposed to be nestable.
+ *
+ * Nesting rules:
+ * 1. parent should be checked when one of its child is checked
+ * Consequences:
+ * * childs get unchecked when parent gets unchecked
+ * * parent will be checked when child is checked even when input
+ * values don't contain parent's value.
+ * 2. parent can be configured not to include it's value when children are
+ * checked
+ * 3. each subtree containing a checked input has to return at least one value
+ * on save()
+ * 4. each option has to have unique value
+ *
+ * Has subset of widget interface - overrides the values in widget
+ * * save(): get values
+ * * update(values): set values
+ * * value_changed: event when change happens
+ * * create: creates HTML
+ */
+IPA.option_widget_base = function(spec, that) {
+
+ spec = spec || {};
+
+ // when that is specified, this constructor behaves like a mixin
+ that = that || {};
+
+ // classic properties
+ that.name = spec.name;
+ that.label = spec.label;
+ that.tooltip = spec.tooltip;
+ that.value_changed = IPA.observer();
+ that.default_value = spec.default_value || null;
+
+ /**
+ * Jquery reference to current node
+ */
+ that.$node = null;
+
+ /**
+ * Type of rendered inputs: ['checkbox', 'radio']
+ */
+ that.input_type = spec.input_type || 'checkbox';
+
+ /**
+ * CSS class for container
+ */
+ that.css_class = spec.css_class || '';
+
+ /**
+ * If it's nested widget
+ */
+ that.nested = !!spec.nested;
+
+ /**
+ * How items should be rendered.
+ *
+ * values: ['inline', 'vertical']
+ */
+ that.layout = spec.layout || 'vertical';
+
+ // private properties
+ that._child_widgets = [];
+ that._input_name = null;
+ that._selector = null;
+ that._option_next_id = 0;
+
+
+ /**
+ * Normalizes options spec
+ */
+ that.prepare_options = function(options) {
+
+ var ret = [];
+
+ if (!options) return options;
+
+ for (var i=0; i<options.length; i++) {
+ ret.push(that.prepare_option(options[i]));
+ }
+
+ return ret;
+ };
+
+ /**
+ * Option has following interface: {
+ * label: String
+ * value: String
+ * nested: Boolean
+ * widget: Widget
+ * combine_values: Boolean, default true. Whether to include this value
+ * if some of its children is specified
+ * }
+ */
+ that.prepare_option = function(spec) {
+
+ var option = spec;
+
+ if (!option) throw {
+ error: 'Invalid option specified',
+ option: option
+ };
+
+ if (typeof option === 'string') {
+ option = {
+ label: option,
+ value: option
+ };
+ } else {
+ if (option.type || option.factory) {
+ var factory = option.factory || IPA.widget_factories[option.type];
+ if (typeof factory !== 'function') throw {
+ error: 'Invalid factory',
+ factory: factory
+ };
+ option.nested = true;
+ option.widget = factory(option);
+ option.widget.value_changed.attach(that.on_input_change);
+
+ that._child_widgets.push(option.widget);
+ }
+ }
+
+ option.combine_values = option.combine_values === undefined ? true :
+ !!option.combine_values;
+
+ return option;
+ };
+
+ that.add_option = function(option, suppress_update) {
+ that.options.push(that.prepare_option(option));
+ if (!suppress_update) that.update_dom();
+ };
+
+ that.update_dom = function() {
+
+ if (that.$node) {
+ var values = that.save();
+ var container = that.$node.parent();
+ that.create(container);
+ that.update(values);
+ }
+ };
+
+ that.create_options = function(container) {
+ for (var i=0; i<that.options.length; i++) {
+ var option_container = that.create_option_container();
+ var option = that.options[i];
+ that.create_option(option, option_container);
+ option_container.appendTo(container);
+ }
+ };
+
+ that.create_option_container = function() {
+ return $('<li/>');
+ };
+
+ that._create_option = function(option, container) {
+ var input_name = that.get_input_name();
+ var id = that._option_next_id + input_name;
+
+ $('<input/>', {
+ id: id,
+ type: that.input_type,
+ name: input_name,
+ value: option.value,
+ title: option.tooltip || that.tooltip,
+ change: that.on_input_change
+ }).appendTo(container);
+
+ $('<label/>', {
+ text: option.label,
+ title: option.tooltip || that.tooltip,
+ 'for': id
+ }).appendTo(container);
+
+ that.new_option_id();
+ };
+
+ that.create_option = function(option, container) {
+
+ that._create_option(option, container);
+
+ if (option.widget) {
+ option.widget.create(container);
+ }
+ };
+
+ that.new_option_id = function() {
+ that._option_next_id++;
+ };
+
+ that.get_input_name = function() {
+
+ if (!that._input_name) {
+ var name = that.name;
+ if (that.input_type === 'radio') {
+ name = IPA.html_util.get_next_id(name);
+ }
+ that._input_name = name;
+ that._selector = 'input[name="'+name+'"]';
+ }
+ return that._input_name;
+ };
+
+ that.create = function(container) {
+ that.destroy();
+ that.create_options(that.$node);
+ var css_class = [that.css_class, 'option_widget', that.layout,
+ that.nested ? 'nested': ''].join(' ');
+
+ that.$node = $('<ul/>', { 'class': css_class });
+ that.create_options(that.$node);
+
+ if (container) that.$node.appendTo(container);
+ };
+
+ that.destroy = function() {
+ if (that.$node) {
+ that.$node.empty();
+ that.$node.remove();
+ }
+
+ for (var i=0; i< that._child_widgets.length; i++) {
+ that._child_widgets[i].destroy();
+ }
+ };
+
+ that.get_option = function(value) {
+ for (var i=0; i<that.options.length; i++) {
+ var option = that.options[i];
+ if (option.value === value) return option;
+ }
+ return null;
+ };
+
+ /**
+ * Get values for specific option and its children.
+ *
+ * If option is not specified, gets values of all options and children.
+ */
+ that.get_values = function(option) {
+
+ var values = [];
+ if (option) {
+ values.push(option.value);
+ if (option.widget) {
+ values.push.apply(values, option.widget.get_values());
+ }
+ } else {
+ for (var i=0; i<that.options.length; i++) {
+ var vals = that.get_values(that.options[i]);
+ values.push.apply(values, vals);
+ }
+ }
+
+ return values;
+ };
+
+ that.on_input_change = function(e) {
+
+ // uncheck child widgets on uncheck of parent option
+ if (that._child_widgets.length > 0) {
+
+ var parents_selected = [];
+
+ $(that._selector+':checked', that.container).each(function() {
+ var value = $(this).val();
+ var option = that.get_option(value);
+ if (option && option.nested) {
+ parents_selected.push(value);
+ }
+ });
+
+ for (var i=0; i<that.options.length; i++) {
+
+ var option = that.options[i];
+
+ if (option.nested) {
+ var selected = parents_selected.indexOf(option.value) > -1;
+ option.widget.set_enabled(selected);
+ }
+ }
+ }
+ that.value_changed.notify([], that);
+ };
+
+ that.save = function() {
+
+ var values = [];
+
+ if (that.$node) {
+
+ $(that._selector+':checked', that.container).each(function() {
+ var value = $(this).val();
+ var child_values = [];
+ var option = that.get_option(value);
+
+ if (option.widget) {
+ child_values = option.widget.save();
+ values.push.apply(values, child_values);
+ }
+
+ // don't use value if cannot be combined with children's value
+ if (!(child_values.length > 0 && !option.combine_values)) {
+ values.push(value);
+ }
+ });
+ }
+
+ return values;
+ };
+
+ that.update = function(values) {
+
+ var check = function(selector, uncheck) {
+ $(selector, that.$node).prop('checked', !uncheck);
+ };
+
+ if (that.$node) {
+
+ // uncheck all inputs
+ check(that._selector, true /*uncheck*/);
+
+ if (values && values.length > 0) {
+
+ // check the option when option or some of its child should be
+ // checked
+ for (var i=0; i<that.options.length; i++) {
+ var option = that.options[i];
+ var opt_vals = that.get_values(option);
+ var has_opt = array.some(values, function(val) {
+ return array.indexOf(opt_vals, val) > -1;
+ });
+
+ if (has_opt) {
+ check(that._selector+'[value="'+ option.value +'"]');
+ }
+ if (option.widget) {
+ option.widget.set_enabled(has_opt);
+ }
+ }
+ } else {
+ // select default if none specified
+ if (that.default_value !== null) {
+ check(that._selector+'[value="'+that.default_value+'"]');
+ } else {
+ // otherwise select empty
+ check(that._selector+'[value=""]');
+ }
+ }
+
+ for (var j=0; j<that._child_widgets.length; j++) {
+ that._child_widgets[j].update(values);
+ }
+ }
+ };
+
+ that.set_enabled = function(enabled) {
+
+ $(that._selector, that.container).prop('disabled', !enabled);
+ if (!enabled) that.clear();
+ for (var i=0; i<that._child_widgets.length;i++){
+ that._child_widgets[i].set_enabled(enabled);
+ }
+ };
+
+
+ that.clear = function() {
+
+ $(that._selector, that.$node).prop('checked', false);
+
+ if (that.default_value) {
+ $(that._selector+'[value="'+that.default_value+'"]', that.$node).
+ prop('checked', true);
+ }
+
+ for (var i=0; i<that._child_widgets.length; i++) {
+ that._child_widgets[i].clear();
+ }
+ };
+
+ that.options = that.prepare_options(spec.options || []);
+
+ that.owb_create = that.create;
+ that.owb_save = that.save;
+ that.owb_update = that.update;
+
+ return that;
+};
+
+IPA.radio_widget = function(spec) {
+
+ spec = spec || {};
+ spec.input_type = spec.input_type || 'radio';
+ spec.layout = spec.layout || 'inline';
+
+ var that = IPA.input_widget(spec);
+ IPA.option_widget_base(spec, that);
+
+ that.create = function(container) {
+ that.widget_create(container);
+ that.owb_create(container);
+ container.addClass('radio-widget');
+
+ if (that.undo) {
+ that.create_undo(container);
+ }
+
+ that.create_error_link(container);
+ };
+ return that;
+};
+
IPA.checkbox_widget = function (spec) {
+ var checked = 'checked';
+
spec = spec || {};
+ spec.input_type = spec.input_type || 'checkbox';
- var that = IPA.input_widget(spec);
+ if (!spec.options) {
+ spec.options = [ { value: checked, label: '' } ];
+ }
- // default value
- that.checked = spec.checked || false;
+ if (spec.checked) spec.default_value = spec.checked;
- that.create = function(container) {
-
- that.widget_create(container);
-
- container.addClass('checkbox-widget');
-
- that.input = $('<input/>', {
- type: 'checkbox',
- name: that.name,
- checked: that.checked,
- title: that.tooltip,
- change: function() {
- that.value_changed.notify([that.save()], that);
- }
- }).appendTo(container);
-
- if (that.undo) {
- that.create_undo(container);
- }
-
- that.create_error_link(container);
- };
+ var that = IPA.radio_widget(spec);
that.save = function() {
- var value = that.input.is(':checked');
- return [value];
+ var values = that.owb_save();
+ return [values.length > 0];
};
that.update = function(values) {
- var value;
-
- if (values && values.length) {
- value = values[0];
- }
+ var value = values ? values[0] : '';
if (typeof value !== 'boolean') {
- // use default value
- value = that.checked;
+ value = that.default_value || '';
+ } else {
+ value = value ? checked : '';
}
-
- that.input.prop('checked', value);
+ that.owb_update([value]);
};
- that.clear = function() {
- that.input.prop('checked', false);
- };
-
- that.checkbox_save = that.save;
-
return that;
};
IPA.checkboxes_widget = function (spec) {
-
spec = spec || {};
-
- var that = IPA.input_widget(spec);
-
- that.options = spec.options || [];
- that.direction = spec.direction || 'vertical';
-
- that.create = function(container) {
-
- that.widget_create(container);
-
- container.addClass('checkboxes-widget');
-
- var vertical = that.direction === 'vertical';
-
- for (var i=0; i<that.options.length; i++) {
- var option = that.options[i];
- $('<input/>', {
- type: 'checkbox',
- name: that.name,
- value: option.value,
- title: that.tooltip
- }).appendTo(container);
-
- $('<label/>', {
- text: option.label,
- title: that.tooltip
- }).appendTo(container);
-
- if (vertical) {
- $('<br/>').appendTo(container);
- }
- }
-
- if (that.undo) {
- that.create_undo(container);
- }
-
- var input = $('input[name="'+that.name+'"]', that.container);
- input.change(function() {
- that.value_changed.notify([that.save()], that);
- });
-
- that.create_error_link(container);
- };
-
- that.save = function() {
- var values = [];
-
- $('input[name="'+that.name+'"]:checked', that.container).each(function() {
- values.push($(this).val());
- });
-
- return values;
- };
-
- that.update = function(values) {
- var inputs = $('input[name="'+that.name+'"]', that.container);
- inputs.prop('checked', false);
-
- for (var j=0; values && j<values.length; j++) {
- var value = values[j];
- var input = $('input[name="'+that.name+'"][value="'+value+'"]', that.container);
- if (!input.length) continue;
- input.prop('checked', true);
- }
- };
-
- that.clear = function() {
- $('input[name="'+that.name+'"]').prop('checked', false);
- };
-
- that.add_option = function(option) {
- that.options.push(option);
- };
-
- // methods that should be invoked by subclasses
- that.checkboxes_update = that.update;
-
- return that;
-};
-
-IPA.radio_widget = function(spec) {
-
- spec = spec || {};
-
- var that = IPA.input_widget(spec);
-
- that.default_value = spec.default_value;
- that.options = spec.options;
-
- that.create = function(container) {
-
- that.widget_create(container);
-
- container.addClass('radio-widget');
-
- var name = IPA.html_util.get_next_id(that.name+'-');
- that.selector = 'input[name="'+name+'"]';
-
- for (var i=0; i<that.options.length; i++) {
- var option = that.options[i];
-
- var id = name+'-'+i;
-
- $('<input/>', {
- id: id,
- type: 'radio',
- name: name,
- value: option.value
- }).appendTo(container);
-
- $('<label/>', {
- text: option.label,
- 'for': id
- }).appendTo(container);
- }
-
- if (that.undo) {
- that.create_undo(container);
- }
-
- var input = $(that.selector, that.container);
- input.change(function() {
- that.value_changed.notify([that.save()], that);
- });
-
- that.create_error_link(container);
- };
-
- that.save = function() {
- var input = $(that.selector+':checked', that.container);
- if (!input.length) return [];
- return [input.val()];
- };
-
- that.update = function(values) {
-
- $(that.selector, that.container).each(function() {
- var input = this;
- input.checked = false;
- });
-
- var value = values && values.length ? values[0] : '';
- var input = $(that.selector+'[value="'+value+'"]', that.container);
- if (input.length) {
- input.prop('checked', true);
- } else if (that.default_value) {
- input = $(that.selector+'[value="'+that.default_value+'"]', that.container);
- input.prop('checked', true);
- }
-
- that.value_changed.notify([that.save()], that);
- };
-
- that.clear = function() {
- $(that.selector, that.container).prop('checked', false);
-
- if (that.default_value) {
- var input = $(that.selector+'[value="'+that.default_value+'"]', that.container);
- input.prop('checked', true);
- }
- };
-
- // methods that should be invoked by subclasses
- that.radio_create = that.create;
- that.radio_save = that.save;
-
+ spec.input_type = spec.input_type || 'checkbox';
+ spec.layout = spec.layout || 'vertical';
+ var that = IPA.radio_widget(spec);
return that;
};
--
1.8.1.4
From 52e4a5b35856ccbf52c5c9705475e95dc4b661c8 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <[email protected]>
Date: Fri, 22 Mar 2013 17:54:12 +0100
Subject: [PATCH] Added Web UI support for service PAC type option: NONE
ipakrbauthzdata accepts [null, 'NONE', 'MS-PAC, 'PAD']
New nesting feature of radios/checkboxes was used to handle mutual exclusivity between
['MS-PAC', 'PAD'], 'NONE' and ''.
https://fedorahosted.org/freeipa/ticket/3404
---
install/ui/src/freeipa/service.js | 30 +++++++++++++++++++++++++++---
install/ui/test/data/ipa_init.json | 6 ++++++
ipalib/plugins/internal.py | 6 ++++++
3 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/install/ui/src/freeipa/service.js b/install/ui/src/freeipa/service.js
index c38cfef1b34d1fe2700d302ab9d0a4cc44e9144b..62c025340d5fa81b6d32e155195098cd4efecbf9 100644
--- a/install/ui/src/freeipa/service.js
+++ b/install/ui/src/freeipa/service.js
@@ -71,8 +71,32 @@ IPA.service.entity = function(spec) {
},
{
name: 'ipakrbauthzdata',
- type: 'checkboxes',
- options: IPA.create_options(['MS-PAC', 'PAD'])
+ type: 'radio',
+ layout: 'vertical',
+ options: [
+ {
+ label: IPA.messages.krbauthzdata.inherited,
+ value: ''
+ },
+ {
+ label: IPA.messages.krbauthzdata.override,
+ name: 'ipakrbauthzdata_override',
+ factory: IPA.option_widget_base,
+ input_type: 'checkbox',
+ value: 'NONE',
+ combine_values: false,
+ options: [
+ {
+ label: IPA.messages.krbauthzdata.mspac,
+ value: 'MS-PAC'
+ },
+ {
+ label: IPA.messages.krbauthzdata.pad,
+ value: 'PAD'
+ }
+ ]
+ }
+ ]
}
]
},
@@ -483,4 +507,4 @@ IPA.service.certificate_policy = function(spec) {
IPA.register('service', IPA.service.entity);
return {};
-});
\ No newline at end of file
+});
diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json
index e563c0e5c0a92f2f5d3230fec41148a8742bc9a6..a75918eb22573d6b4114242d99f972f59050d060 100644
--- a/install/ui/test/data/ipa_init.json
+++ b/install/ui/test/data/ipa_init.json
@@ -131,6 +131,12 @@
"search": "Search"
},
"false": "False",
+ "krbauthzdata": {
+ "inherited": "Inherited from server configuration",
+ "mspac": "MS-PAC",
+ "override": "Override inherited settings",
+ "pad": "PAD"
+ },
"login": {
"form_auth": "To login with username and password, enter them in the fields below then click Login.",
"header": "Logged In As",
diff --git a/ipalib/plugins/internal.py b/ipalib/plugins/internal.py
index 85bf7d213afa6f83f1119e1ba3ed600b6385e952..4cce2c607fc53b98857cc9c5a2b82ea96b7b11e1 100644
--- a/ipalib/plugins/internal.py
+++ b/ipalib/plugins/internal.py
@@ -266,6 +266,12 @@ class i18n_messages(Command):
"search": _("Search"),
},
"false": _("False"),
+ "krbauthzdata": {
+ "inherited": _("Inherited from server configuration"),
+ "mspac": _("MS-PAC"),
+ "override": _("Override inherited settings"),
+ "pad": _("PAD"),
+ },
"login": {
"form_auth": _("To login with username and password, enter them in the fields below then click Login."),
"header": _("Logged In As"),
--
1.8.1.4
_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel