[form] Reimplement the "login" user interface

Rewrite the code implementing the "login" user interface to use a
predefined interactive form.  The command "login" then becomes roughly
equivalent to:

  #!ipxe

  form
  item          username   Username
  item --secret password   Password
  present

with the result that login form customisations (e.g. to add a Windows
domain name) may be implemented within the scripting language.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/1243/head
Michael Brown 2024-06-20 15:42:48 -07:00
parent f417f0b6a5
commit 162cc51b6d
1 changed files with 33 additions and 63 deletions

View File

@ -29,72 +29,42 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* *
*/ */
#include <string.h> #include <ipxe/dynui.h>
#include <stdlib.h>
#include <errno.h>
#include <curses.h>
#include <ipxe/console.h>
#include <ipxe/settings.h>
#include <ipxe/label.h>
#include <ipxe/editbox.h>
#include <ipxe/keys.h>
#include <ipxe/ansicol.h>
#include <ipxe/login_ui.h> #include <ipxe/login_ui.h>
/* Screen layout */ static struct dynamic_item username;
#define USERNAME_LABEL_ROW ( ( LINES / 2U ) - 4U ) static struct dynamic_item password;
#define USERNAME_ROW ( ( LINES / 2U ) - 2U )
#define PASSWORD_LABEL_ROW ( ( LINES / 2U ) + 2U ) static struct dynamic_ui login = {
#define PASSWORD_ROW ( ( LINES / 2U ) + 4U ) .items = {
#define WIDGET_COL ( ( COLS / 2U ) - 10U ) .prev = &password.list,
#define WIDGET_WIDTH 20U .next = &username.list,
},
.count = 2,
};
static struct dynamic_item username = {
.list = {
.prev = &login.items,
.next = &password.list,
},
.name = "username",
.text = "Username",
.index = 0,
};
static struct dynamic_item password = {
.list = {
.prev = &username.list,
.next = &login.items,
},
.name = "password",
.text = "Password",
.index = 1,
.flags = DYNUI_SECRET,
};
int login_ui ( void ) { int login_ui ( void ) {
char *username;
char *password;
struct {
struct widgets widgets;
struct label username_label;
struct label password_label;
struct edit_box username_box;
struct edit_box password_box;
} widgets;
int rc;
/* Fetch current setting values */ return show_form ( &login );
fetchf_setting_copy ( NULL, &username_setting, NULL, NULL, &username );
fetchf_setting_copy ( NULL, &password_setting, NULL, NULL, &password );
/* Construct user interface */
memset ( &widgets, 0, sizeof ( widgets ) );
init_widgets ( &widgets.widgets );
init_label ( &widgets.username_label, USERNAME_LABEL_ROW, WIDGET_COL,
WIDGET_WIDTH, "Username" );
init_label ( &widgets.password_label, PASSWORD_LABEL_ROW, WIDGET_COL,
WIDGET_WIDTH, "Password" );
init_editbox ( &widgets.username_box, USERNAME_ROW, WIDGET_COL,
WIDGET_WIDTH, 0, &username );
init_editbox ( &widgets.password_box, PASSWORD_ROW, WIDGET_COL,
WIDGET_WIDTH, WIDGET_SECRET, &password );
add_widget ( &widgets.widgets, &widgets.username_label.widget );
add_widget ( &widgets.widgets, &widgets.password_label.widget );
add_widget ( &widgets.widgets, &widgets.username_box.widget );
add_widget ( &widgets.widgets, &widgets.password_box.widget );
/* Present user interface */
if ( ( rc = widget_ui ( &widgets.widgets ) ) != 0 )
goto err_ui;
/* Store settings on successful completion */
if ( ( rc = storef_setting ( NULL, &username_setting, username ) ) !=0)
goto err_store_username;
if ( ( rc = storef_setting ( NULL, &password_setting, password ) ) !=0)
goto err_store_password;
err_store_username:
err_store_password:
err_ui:
free ( username );
free ( password );
return rc;
} }