1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

os: add input_password(prompt) and unit tests (#15507)

This commit is contained in:
Subhomoy Haldar 2022-08-23 20:47:38 +05:30 committed by GitHub
parent d08edf8cba
commit 3b42f18dee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 111 additions and 0 deletions

View File

@ -29,6 +29,7 @@ jobs:
## The following is needed for examples/wkhtmltopdf.v ## The following is needed for examples/wkhtmltopdf.v
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
sudo apt-get install --quiet -y xfonts-75dpi xfonts-base sudo apt-get install --quiet -y xfonts-75dpi xfonts-base
sudo apt-get install --quiet -y expect
sudo dpkg -i wkhtmltox_0.12.6-1.focal_amd64.deb sudo dpkg -i wkhtmltox_0.12.6-1.focal_amd64.deb
- name: Build v - name: Build v
run: | run: |
@ -92,6 +93,11 @@ jobs:
./v2 -o v3 -usecache cmd/v ./v2 -o v3 -usecache cmd/v
./v3 version ./v3 version
./v3 -o tetris -usecache examples/tetris/tetris.v ./v3 -o tetris -usecache examples/tetris/tetris.v
- name: Test password input
run: |
./v examples/password
./v examples/password/password_ci.vsh
ubuntu-tcc-boehm-gc: ubuntu-tcc-boehm-gc:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
@ -239,6 +245,10 @@ jobs:
./v2 -o v3 -usecache cmd/v ./v2 -o v3 -usecache cmd/v
./v3 version ./v3 version
./v3 -o tetris -usecache examples/tetris/tetris.v ./v3 -o tetris -usecache examples/tetris/tetris.v
- name: Test password input
run: |
./v examples/password
./v examples/password/password_ci.vsh
ubuntu: ubuntu:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04

View File

@ -0,0 +1,8 @@
#!/usr/bin/expect
spawn ./password
expect "Enter your password : "
send "Sample\r"
expect "Confirm password : "
send "Sample\r"
expect "Password confirmed! You entered: Sample ."
expect eof

View File

@ -0,0 +1,8 @@
#!/usr/bin/expect
spawn ./password
expect "Enter your password : "
send "Sample123\r"
expect "Confirm password : "
send "Sample234\r"
expect "Passwords do not match ."
expect eof

View File

@ -0,0 +1,14 @@
module main
import os
fn main() {
original_password := os.input_password('Enter your password : ')!
repeated_password := os.input_password('Confirm password : ')!
if original_password == repeated_password {
println('Password confirmed! You entered: $original_password .')
} else {
println('Passwords do not match .')
}
}

View File

@ -0,0 +1,3 @@
chdir('examples/password')?
assert execute('./correct.expect').exit_code == 0
assert execute('./incorrect.expect').exit_code == 0

42
vlib/os/password_nix.c.v Normal file
View File

@ -0,0 +1,42 @@
module os
#include <termios.h>
pub struct C.termios {
mut:
c_iflag int
c_oflag int
c_cflag int
c_lflag int
c_cc [20]u8
}
fn C.tcgetattr(fd int, ptr &C.termios) int
fn C.tcsetattr(fd int, action int, const_ptr &C.termios)
// input_password prompts the user for a password-like secret. It disables
// the terminal echo during user input and resets it back to normal when done.
pub fn input_password(prompt string) !string {
if is_atty(1) <= 0 || getenv('TERM') == 'dumb' {
return error('Could not obtain password discretely.')
}
old_state := C.termios{}
if unsafe { C.tcgetattr(0, &old_state) } != 0 {
return last_error()
}
defer {
unsafe { C.tcsetattr(0, C.TCSANOW, &old_state) }
println('')
}
mut new_state := old_state
new_state.c_lflag &= int(~u32(C.ECHO)) // Disable echoing of characters
unsafe { C.tcsetattr(0, C.TCSANOW, &new_state) }
password := input_opt(prompt) or { return error('Failed to read password') }
return password
}

View File

@ -0,0 +1,26 @@
module os
#include <windows.h>
// input_password prompts the user for a password-like secret. It disables
// the terminal echo during user input and resets it back to normal when done.
pub fn input_password(prompt string) !string {
if is_atty(1) <= 0 || getenv('TERM') == 'dumb' {
return error('Could not obtain password discretely.')
}
std_handle := C.GetStdHandle(C.STD_INPUT_HANDLE)
mut mode := u32(0)
unsafe { C.GetConsoleMode(std_handle, &mode) }
unsafe { C.SetConsoleMode(std_handle, mode & (~u32(C.ENABLE_ECHO_INPUT))) }
defer {
unsafe { C.SetConsoleMode(std_handle, &mode) }
println('')
}
password := input_opt(prompt) or { return error('Failed to read password') }
return password
}