mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Web UI password is going to expire in n days notification
This patch adds pending password expiration notification support to Web UI. When user's password is going to expire in less or equal than configure days a bold red text 'Your password expires in N days.' and a link 'Reset your password' are shown in Web UI's header (on the left next to 'Logged in as...'). Clicking on 'Reset your password link' opens IPA.user_password_dialog. Successful reset of own password will reload user's information (whoami) and update header (it will most likely hide the warning and link). https://fedorahosted.org/freeipa/ticket/2625
This commit is contained in:
parent
a6ff85f425
commit
5b7084aeb5
@ -125,7 +125,7 @@ IPA.section_builder = function(spec) {
|
||||
section_spec.entity = that.container.entity;
|
||||
section_spec.facet = that.container;
|
||||
|
||||
if (!section_spec.label && section_spec.name) {
|
||||
if (!section_spec.label && section_spec.name && that.container.entity) {
|
||||
var obj_messages = IPA.messages.objects[that.container.entity.name];
|
||||
section_spec.label = obj_messages[section_spec.name];
|
||||
}
|
||||
|
@ -70,6 +70,7 @@
|
||||
<a href="#"><img src="images/ipa-logo.png" /><img src="images/ipa-banner.png" /></a>
|
||||
</span>
|
||||
<span class="header-right">
|
||||
<span class="header-passwordexpires"></span>
|
||||
<span id="loggedinas" class="header-loggedinas">
|
||||
<a href="#"><span id="login_header">Logged in as</span>: <strong>user@FREEIPA.ORG</strong></a>
|
||||
</span>
|
||||
|
@ -240,6 +240,18 @@ body {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* ---- Password expiration */
|
||||
|
||||
.header-passwordexpires {
|
||||
margin-right: 30px;
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-passwordexpires a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* ---- Logged-in As ---- */
|
||||
.header-right {
|
||||
float: right;
|
||||
|
@ -116,18 +116,15 @@ var IPA = function() {
|
||||
}));
|
||||
|
||||
batch.add_command(IPA.command({
|
||||
entity: 'user',
|
||||
method: 'find',
|
||||
options: {
|
||||
whoami: true,
|
||||
all: true
|
||||
},
|
||||
entity: 'config',
|
||||
method: 'show',
|
||||
on_success: function(data, text_status, xhr) {
|
||||
that.whoami = data.result[0];
|
||||
that.principal = that.whoami.krbprincipalname[0];
|
||||
that.server_config = data.result;
|
||||
}
|
||||
}));
|
||||
|
||||
batch.add_command(that.get_whoami_command(true));
|
||||
|
||||
batch.add_command(IPA.command({
|
||||
method: 'env',
|
||||
on_success: function(data, text_status, xhr) {
|
||||
@ -144,9 +141,27 @@ var IPA = function() {
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
|
||||
batch.execute();
|
||||
};
|
||||
|
||||
that.get_whoami_command = function(batch) {
|
||||
return IPA.command({
|
||||
entity: 'user',
|
||||
method: 'find',
|
||||
options: {
|
||||
whoami: true,
|
||||
all: true
|
||||
},
|
||||
on_success: function(data, text_status, xhr) {
|
||||
that.whoami = batch ? data.result[0] : data.result.result[0];
|
||||
that.principal = that.whoami.krbprincipalname[0];
|
||||
that.update_password_expiration();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
that.init_metadata = function(params) {
|
||||
|
||||
var objects = IPA.command({
|
||||
@ -459,6 +474,86 @@ IPA.reset_password = function(username, old_password, new_password) {
|
||||
return result;
|
||||
};
|
||||
|
||||
IPA.update_password_expiration = function() {
|
||||
|
||||
var now, expires, notify_days, diff, message, container;
|
||||
|
||||
expires = IPA.whoami.krbpasswordexpiration;
|
||||
expires = expires ? IPA.parse_utc_date(expires[0]) : null;
|
||||
|
||||
notify_days = IPA.server_config.ipapwdexpadvnotify;
|
||||
notify_days = notify_days ? notify_days[0] : 0;
|
||||
|
||||
now = new Date();
|
||||
|
||||
container = $('.header-passwordexpires');
|
||||
container.empty();
|
||||
|
||||
if (expires) {
|
||||
|
||||
diff = expires.getTime() - now.getTime();
|
||||
diff = Math.floor(diff / 86400000);
|
||||
|
||||
if (diff <= notify_days) {
|
||||
message = IPA.messages.password.expires_in;
|
||||
message = message.replace('${days}', diff);
|
||||
container.append(message + ' ');
|
||||
$('<a/>', {
|
||||
href: '#reset-password',
|
||||
click: function() {
|
||||
IPA.password_selfservice();
|
||||
return false;
|
||||
},
|
||||
text: IPA.messages.password.reset_password_sentence,
|
||||
title: IPA.messages.password.reset_password
|
||||
}).appendTo(container);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IPA.password_selfservice = function() {
|
||||
var reset_dialog = IPA.user_password_dialog({
|
||||
self_service: true,
|
||||
on_success: function() {
|
||||
var command = IPA.get_whoami_command();
|
||||
command.execute();
|
||||
|
||||
alert(IPA.messages.password.password_change_complete);
|
||||
reset_dialog.close();
|
||||
}
|
||||
});
|
||||
reset_dialog.open();
|
||||
};
|
||||
|
||||
IPA.parse_utc_date = function(value) {
|
||||
|
||||
if (!value) return null;
|
||||
|
||||
// verify length
|
||||
if (value.length != 'YYYYmmddHHMMSSZ'.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// We only handle GMT
|
||||
if (value.charAt(value.length -1) !== 'Z') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var date = new Date();
|
||||
|
||||
date.setUTCFullYear(
|
||||
value.substring(0, 4), // YYYY
|
||||
value.substring(4, 6)-1, // mm (0-11)
|
||||
value.substring(6, 8)); // dd (1-31)
|
||||
|
||||
date.setUTCHours(
|
||||
value.substring(8, 10), // HH (0-23)
|
||||
value.substring(10, 12), // MM (0-59)
|
||||
value.substring(12, 14)); // SS (0-59)
|
||||
|
||||
return date;
|
||||
};
|
||||
|
||||
/**
|
||||
* Call an IPA command over JSON-RPC.
|
||||
*
|
||||
|
@ -439,6 +439,7 @@
|
||||
"password": {
|
||||
"current_password": "Current Password",
|
||||
"current_password_required": "Current password is required",
|
||||
"expires_in": "Your password expires in ${days} days.",
|
||||
"invalid_password": "The password or username you entered is incorrect.",
|
||||
"new_password": "New Password",
|
||||
"new_password_required": "New password is required",
|
||||
@ -447,6 +448,7 @@
|
||||
"password_must_match": "Passwords must match",
|
||||
"reset_failure": "Password reset was not successful.",
|
||||
"reset_password": "Reset Password",
|
||||
"reset_password_sentence": "Reset your password.",
|
||||
"verify_password": "Verify Password"
|
||||
},
|
||||
"search": {
|
||||
@ -499,6 +501,59 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"error": null,
|
||||
"result": {
|
||||
"dn": "cn=ipaconfig,cn=etc,dc=test,dc=example,dc=com",
|
||||
"ipacertificatesubjectbase": [
|
||||
"O=EXAMPLE.COM"
|
||||
],
|
||||
"ipaconfigstring": [
|
||||
"AllowNThash"
|
||||
],
|
||||
"ipadefaultemaildomain": [
|
||||
"example.com"
|
||||
],
|
||||
"ipadefaultloginshell": [
|
||||
"/bin/sh"
|
||||
],
|
||||
"ipadefaultprimarygroup": [
|
||||
"ipausers"
|
||||
],
|
||||
"ipagroupsearchfields": [
|
||||
"cn,description"
|
||||
],
|
||||
"ipahomesrootdir": [
|
||||
"/home"
|
||||
],
|
||||
"ipamaxusernamelength": [
|
||||
"32"
|
||||
],
|
||||
"ipamigrationenabled": [
|
||||
"FALSE"
|
||||
],
|
||||
"ipapwdexpadvnotify": [
|
||||
"4"
|
||||
],
|
||||
"ipasearchrecordslimit": [
|
||||
"100"
|
||||
],
|
||||
"ipasearchtimelimit": [
|
||||
"2"
|
||||
],
|
||||
"ipaselinuxusermapdefault": [
|
||||
"guest_u:s0"
|
||||
],
|
||||
"ipaselinuxusermaporder": [
|
||||
"guest_u:s0$xguest_u:s0$user_u:s0-s0:c0.c1023$staff_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023"
|
||||
],
|
||||
"ipausersearchfields": [
|
||||
"uid,givenname,sn,telephonenumber,ou,title"
|
||||
]
|
||||
},
|
||||
"summary": null,
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"count": 1,
|
||||
"error": null,
|
||||
@ -534,7 +589,7 @@
|
||||
"20120110142413Z"
|
||||
],
|
||||
"krbpasswordexpiration": [
|
||||
"20111212052109Z"
|
||||
"20141212052109Z"
|
||||
],
|
||||
"krbprincipalname": [
|
||||
"admin@DEV.EXAMPLE.COM"
|
||||
|
@ -503,9 +503,18 @@ IPA.user_password_dialog = function(spec) {
|
||||
});
|
||||
|
||||
var that = IPA.dialog(spec);
|
||||
that.success_handler = spec.on_success;
|
||||
that.error_handler = spec.on_error;
|
||||
that.self_service = spec.self_service; //option to force self-service
|
||||
|
||||
that.get_pkey = function() {
|
||||
return IPA.nav.get_state('user-pkey');
|
||||
var pkey;
|
||||
if (that.self_service) {
|
||||
pkey = IPA.whoami.uid[0];
|
||||
} else {
|
||||
pkey = IPA.nav.get_state('user-pkey');
|
||||
}
|
||||
return pkey;
|
||||
};
|
||||
|
||||
that.is_self_service = function() {
|
||||
@ -575,17 +584,8 @@ IPA.user_password_dialog = function(spec) {
|
||||
pkey,
|
||||
current_password,
|
||||
new_password,
|
||||
function(data, text_status, xhr) {
|
||||
alert(IPA.messages.password.password_change_complete);
|
||||
that.close();
|
||||
// refresh password expiration field
|
||||
var facet = IPA.current_entity.get_facet();
|
||||
facet.refresh();
|
||||
},
|
||||
function(xhr, text_status, error_thrown) {
|
||||
that.close();
|
||||
}
|
||||
);
|
||||
that.on_reset_success,
|
||||
that.on_reset_error);
|
||||
};
|
||||
|
||||
that.set_password = function(pkey, current_password, password, on_success, on_error) {
|
||||
@ -604,6 +604,34 @@ IPA.user_password_dialog = function(spec) {
|
||||
command.execute();
|
||||
};
|
||||
|
||||
that.on_reset_success = function(data, text_status, xhr) {
|
||||
|
||||
if (that.success_handler) {
|
||||
that.success_handler.call(this, data, text_status, xhr);
|
||||
} else {
|
||||
alert(IPA.messages.password.password_change_complete);
|
||||
that.close();
|
||||
|
||||
// refresh password expiration field
|
||||
var facet = IPA.current_entity.get_facet();
|
||||
facet.refresh();
|
||||
|
||||
if (that.is_self_service()) {
|
||||
var command = IPA.get_whoami_command();
|
||||
command.execute();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
that.on_reset_error = function(xhr, text_status, error_thrown) {
|
||||
|
||||
if (that.error_handler) {
|
||||
that.error_handler.call(this, xhr, text_status, error_thrown);
|
||||
} else {
|
||||
that.close();
|
||||
}
|
||||
};
|
||||
|
||||
that.create_buttons();
|
||||
|
||||
return that;
|
||||
|
@ -1125,29 +1125,8 @@ IPA.utc_date_formatter = function(spec) {
|
||||
that.format = function(value) {
|
||||
|
||||
if (!value) return '';
|
||||
|
||||
// verify length
|
||||
if (value.length != 'YYYYmmddHHMMSSZ'.length) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/* We only handle GMT */
|
||||
if (value.charAt(value.length -1) !== 'Z') {
|
||||
return value;
|
||||
}
|
||||
|
||||
var date = new Date();
|
||||
|
||||
date.setUTCFullYear(
|
||||
value.substring(0, 4), // YYYY
|
||||
value.substring(4, 6)-1, // mm (0-11)
|
||||
value.substring(6, 8)); // dd (1-31)
|
||||
|
||||
date.setUTCHours(
|
||||
value.substring(8, 10), // HH (0-23)
|
||||
value.substring(10, 12), // MM (0-59)
|
||||
value.substring(12, 14)); // SS (0-59)
|
||||
|
||||
var date = IPA.parse_utc_date(value);
|
||||
if (!date) return value;
|
||||
return date.toString();
|
||||
};
|
||||
|
||||
|
@ -578,6 +578,7 @@ class i18n_messages(Command):
|
||||
"password": {
|
||||
"current_password": _("Current Password"),
|
||||
"current_password_required": _("Current password is required"),
|
||||
"expires_in": _("Your password expires in ${days} days."),
|
||||
"invalid_password": _("The password or username you entered is incorrect."),
|
||||
"new_password": _("New Password"),
|
||||
"new_password_required": _("New password is required"),
|
||||
@ -586,6 +587,7 @@ class i18n_messages(Command):
|
||||
"password_must_match": _("Passwords must match"),
|
||||
"reset_failure": _("Password reset was not successful."),
|
||||
"reset_password": _("Reset Password"),
|
||||
"reset_password_sentence": _("Reset your password."),
|
||||
"verify_password": _("Verify Password"),
|
||||
},
|
||||
"search": {
|
||||
|
Loading…
Reference in New Issue
Block a user