/
TextPasswordChallenge.io
98 lines (89 loc) · 2.81 KB
/
TextPasswordChallenge.io
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Challenge := Object clone do (
//doc challenge returns the identity if successful, or nil
challenge := method(session,
return nil
)
)
TextPasswordChallenge := Challenge clone do (
authentication ::= nil
//doc challenge the session by displaying username and password prompts.
challenge := method(session,
identity := PasswordIdentity clone
usernamePrompt := "Username: "
usernameCorrect := false
while(usernameCorrect not,
readUsername(session, identity, usernamePrompt)
if(authentication authenticate(identity) == nil) then (
newIdentity := handleUnknownIdentity(session, identity)
if(newIdentity == nil) then (
usernamePrompt := "What is your name, then? "
) else (
usernameCorrect := true
return identity
)
) else (
usernameCorrect := true
return handleKnownIdentity(session, identity)
)
)
)
readUsername := method(session, identity, prompt,
session channel write(prompt)
if(username := session channel readln,
identity setUsername(username)
)
)
handleKnownIdentity := method(session, identity,
loginAttemptsLeft := 3
readPassword(session, identity, "Password: ")
authenticated := authentication authenticate(identity)
while(authenticated == false and loginAttemptsLeft > 0,
loginAttemptsLeft := loginAttemptsLeft - 1
readPassword(session, identity,
"That's not the right password. I'll give you #{loginAttemptsLeft} more tries: " interpolate)
authenticated := authentication authenticate(identity)
)
if(authenticated not) then (
session channel writeln("Sorry, too many login attempts.")
session close
return nil
) else (
handleIdentityAuthenticated(session, identity)
return identity
)
)
readPassword := method(session, identity, prompt,
session channel write(prompt)
if(password := session channel readln,
identity setPassword(password)
)
)
handleUnknownIdentity := method(session, identity,
session channel write("I don't think I know you. Are you new here (y/n)? ")
response := session channel readln
pwPrompt := "Please choose a password: "
if(list("y", "yes") contains(response asMutable lowercase)) then (
confirmed := false
while(confirmed not,
readPassword(session, identity, pwPrompt)
confirmed := confirmPassword(session, identity, "Please confirm your password: ")
if(confirmed not,
pwPrompt := "Those passwords do not match. Please enter a new password: "
)
)
authentication store insert(identity)
session channel writeln("Welcome.")
return identity
) else (
return nil
)
)
confirmPassword := method(session, identity, prompt,
session channel write(prompt)
password := session channel readln
return identity clone setPassword(password) authenticatesAs(identity)
)
handleIdentityAuthenticated := method(session, identity,
return identity
)
)