Commit 043f7ed9 authored by Maksim Ivanov's avatar Maksim Ivanov Committed by Commit Bot

Display errors in smart card PIN during SAML login

This adds implementation that displays a message to the user when
a problem occurs in the security token PIN dialog during SAML user
sign-in (a.k.a. smart card login).

The problem message consists of an icon, the error's text and the
number of left attempts.

Bug: 964069
Change-Id: Ia4014ebbbac49e59db2864ea8fe50a6b94034bde
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1753002Reviewed-by: default avatarDenis Kuznetsov <antrim@chromium.org>
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692067}
parent 885902a0
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// This inclusion is types-only. No actual code to execute.
// <include src="oobe_types.js">
// <include src="oobe_dialog_host_behavior.js"> // <include src="oobe_dialog_host_behavior.js">
// <include src="login_screen_behavior.js"> // <include src="login_screen_behavior.js">
// <include src="gaia_buttons.js"> // <include src="gaia_buttons.js">
......
...@@ -1475,7 +1475,6 @@ Polymer({ ...@@ -1475,7 +1475,6 @@ Polymer({
// previous dialog depending on this flag. // previous dialog depending on this flag.
this.pinDialogParameters_ = parameters; this.pinDialogParameters_ = parameters;
this.$.pinDialog.reset();
this.pinDialogResultReported_ = false; this.pinDialogResultReported_ = false;
}, },
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
* found in the LICENSE file. */ * found in the LICENSE file. */
#pinKeyboardContainer { #pinKeyboardContainer {
padding-top: 60px; margin-top: 36px;
position: relative;
} }
#pinKeyboard { #pinKeyboard {
...@@ -35,3 +36,19 @@ ...@@ -35,3 +36,19 @@
color: var(--google-blue-500); color: var(--google-blue-500);
text-decoration: none; text-decoration: none;
} }
#errorContainer {
color: var(--google-red-600);
font-size: 10px;
font-weight: 500;
position: absolute;
text-align: center;
top: 40px;
width: 100%;
}
#errorIcon {
--iron-icon-width: 20px;
--iron-icon-height: 20px;
margin-inline-end: 3px;
}
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. --> found in the LICENSE file. -->
<link rel="import" href="chrome://resources/cr_elements/icons.html">
<dom-module id="security-token-pin"> <dom-module id="security-token-pin">
<link rel="stylesheet" href="oobe_dialog_host.css"> <link rel="stylesheet" href="oobe_dialog_host.css">
<link rel="stylesheet" href="oobe_flex_layout.css"> <link rel="stylesheet" href="oobe_flex_layout.css">
...@@ -23,7 +25,15 @@ ...@@ -23,7 +25,15 @@
</div> </div>
<div slot="footer"> <div slot="footer">
<div id="pinKeyboardContainer"> <div id="pinKeyboardContainer">
<pin-keyboard id="pinKeyboard"></pin-keyboard> <pin-keyboard id="pinKeyboard"
has-error="[[hasError_(parameters, userEdited_)]]"
on-pin-change="onPinChange_">
<div id="errorContainer" problem
hidden="[[!hasError_(parameters, userEdited_)]]">
<iron-icon id="errorIcon" icon="cr:error-outline"></iron-icon>
[[getErrorText_(parameters, userEdited_)]]
</div>
</pin-keyboard>
</div> </div>
</div> </div>
<div slot="bottom-buttons" class="layout horizontal justified"> <div slot="bottom-buttons" class="layout horizontal justified">
......
...@@ -16,9 +16,14 @@ Polymer({ ...@@ -16,9 +16,14 @@ Polymer({
/** /**
* Contains the OobeTypes.SecurityTokenPinDialogParameters object. It can be * Contains the OobeTypes.SecurityTokenPinDialogParameters object. It can be
* null when our element isn't used. * null when our element isn't used.
*
* Changing this field resets the dialog state. (Please note that, due to
* the Polymer's limitation, only assigning a new object is observed;
* changing just a subproperty won't work.)
*/ */
parameters: { parameters: {
type: Object, type: Object,
observer: 'onParametersChanged_',
}, },
/** /**
...@@ -30,14 +35,16 @@ Polymer({ ...@@ -30,14 +35,16 @@ Polymer({
type: Boolean, type: Boolean,
value: false, value: false,
}, },
},
/** /**
* Resets the dialog to the initial state. * Whether the user has made changes in the input field since the dialog
*/ * was initialized or reset.
reset: function() { * @private
this.$.pinKeyboard.value = ''; */
this.processingCompletion_ = false; userEdited_: {
type: Boolean,
value: false,
}
}, },
/** /**
...@@ -62,4 +69,104 @@ Polymer({ ...@@ -62,4 +69,104 @@ Polymer({
this.processingCompletion_ = true; this.processingCompletion_ = true;
this.fire('completed', this.$.pinKeyboard.value); this.fire('completed', this.$.pinKeyboard.value);
}, },
/**
* Observer that is called when the |parameters| property gets changed.
* @private
*/
onParametersChanged_: function() {
// Reset the dialog to the initial state.
this.$.pinKeyboard.value = '';
this.processingCompletion_ = false;
this.userEdited_ = false;
},
/**
* Observer that is called when the user changes the PIN input field.
* @private
*/
onPinChange_: function() {
this.userEdited_ = true;
},
/**
* Returns whether an error message should be displayed to the user.
* @param {OobeTypes.SecurityTokenPinDialogParameters} parameters
* @param {boolean} userEdited
* @return {boolean}
* @private
*/
hasError_: function(parameters, userEdited) {
if (!parameters)
return false;
if (parameters.attemptsLeft != -1)
return true;
return parameters.errorLabel !=
OobeTypes.SecurityTokenPinDialogErrorType.NONE &&
!userEdited;
},
/**
* Returns the text of the error message to be displayed to the user.
* @param {OobeTypes.SecurityTokenPinDialogParameters} parameters
* @param {boolean} userEdited
* @return {string}
* @private
*/
getErrorText_: function(parameters, userEdited) {
if (!this.hasError_(parameters, userEdited))
return '';
return [
this.formatErrorLabel_(parameters, userEdited),
this.formatAttemptsLeft_(parameters)
].join(' ');
},
/**
* Returns the formatted PIN error label to be displayed to the user.
* @param {OobeTypes.SecurityTokenPinDialogParameters} parameters
* @param {boolean} userEdited
* @return {string}
* @private
*/
formatErrorLabel_: function(parameters, userEdited) {
if (!parameters || userEdited)
return '';
var errorLabel = '';
// TODO(crbug.com/964069): Make strings localized.
switch (parameters.errorLabel) {
case OobeTypes.SecurityTokenPinDialogErrorType.NONE:
break;
case OobeTypes.SecurityTokenPinDialogErrorType.UNKNOWN:
errorLabel = 'Unknown error.';
break;
case OobeTypes.SecurityTokenPinDialogErrorType.INVALID_PIN:
errorLabel = 'Invalid PIN.';
break;
case OobeTypes.SecurityTokenPinDialogErrorType.INVALID_PUK:
errorLabel = 'Invalid PUK.';
break;
case OobeTypes.SecurityTokenPinDialogErrorType.MAX_ATTEMPTS_EXCEEDED:
errorLabel = 'Maximum allowed attempts exceeded.';
break;
default:
assertNotReached(`Unexpected enum value: ${parameters.errorLabel}`);
}
if (errorLabel && parameters.enableUserInput)
errorLabel = `${errorLabel} Please try again.`;
return errorLabel;
},
/**
* Returns the formatted PIN attempts left count to be displayed to the user.
* @param {OobeTypes.SecurityTokenPinDialogParameters} parameters
* @return {string}
* @private
*/
formatAttemptsLeft_: function(parameters) {
if (!parameters || parameters.attemptsLeft == -1)
return '';
// TODO(crbug.com/964069): Make the string localized.
return `Attempts left: ${parameters.attemptsLeft}`;
},
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment