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:
parent
d08edf8cba
commit
3b42f18dee
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@ -29,6 +29,7 @@ jobs:
|
||||
## 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
|
||||
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
|
||||
- name: Build v
|
||||
run: |
|
||||
@ -92,6 +93,11 @@ jobs:
|
||||
./v2 -o v3 -usecache cmd/v
|
||||
./v3 version
|
||||
./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:
|
||||
runs-on: ubuntu-20.04
|
||||
@ -239,6 +245,10 @@ jobs:
|
||||
./v2 -o v3 -usecache cmd/v
|
||||
./v3 version
|
||||
./v3 -o tetris -usecache examples/tetris/tetris.v
|
||||
- name: Test password input
|
||||
run: |
|
||||
./v examples/password
|
||||
./v examples/password/password_ci.vsh
|
||||
|
||||
ubuntu:
|
||||
runs-on: ubuntu-20.04
|
||||
|
8
examples/password/correct.expect
Executable file
8
examples/password/correct.expect
Executable 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
|
8
examples/password/incorrect.expect
Executable file
8
examples/password/incorrect.expect
Executable 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
|
14
examples/password/password.v
Normal file
14
examples/password/password.v
Normal 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 .')
|
||||
}
|
||||
}
|
3
examples/password/password_ci.vsh
Normal file
3
examples/password/password_ci.vsh
Normal 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
42
vlib/os/password_nix.c.v
Normal 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
|
||||
}
|
26
vlib/os/password_windows.c.v
Normal file
26
vlib/os/password_windows.c.v
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user