-
Notifications
You must be signed in to change notification settings - Fork 264
/
Copy pathauth_code.go
177 lines (154 loc) · 4.23 KB
/
auth_code.go
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
* @Copyright Reserved By Janusec (https://www.janusec.com/).
* @Author: U2
* @Date: 2020-05-17 21:45:58
* @Last Modified: U2, 2020-05-17 21:45:58
*/
package gateway
import (
"encoding/base64"
"fmt"
"net/http"
"strconv"
"text/template"
"janusec/usermgmt"
"janusec/utils"
qrcode "github.com/skip2/go-qrcode"
)
var (
authCodeUITemplate = template.Must(template.New("authcode").Parse(authcodeTemplate))
)
// AuthCodeContext authenticator code context
type AuthCodeContext struct {
UID string
TOTPKey string
ImageData string
}
// AuthCodeVerifyFunc Register TOTP in Mobile APP
func AuthCodeVerifyFunc(w http.ResponseWriter, r *http.Request) {
uid := r.FormValue("uid")
totpCode := r.FormValue("code")
totpCodeInt, _ := strconv.ParseUint(totpCode, 10, 32)
totpItem, _ := usermgmt.GetTOTPByUID(uid) //data.DAL.GetTOTPItemByUID(uid)
verifyOK := usermgmt.VerifyCode(totpItem.TOTPKey, uint32(totpCodeInt))
if verifyOK {
_, err := usermgmt.UpdateTOTPVerified(totpItem.ID)
if err != nil {
utils.DebugPrintln("UpdateTOTPVerified error", err)
}
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
http.Redirect(w, r, "/oauth/code/register?uid="+uid, http.StatusTemporaryRedirect)
}
// ShowAuthCodeRegisterUI used for Authenticator Code register UI
func ShowAuthCodeRegisterUI(w http.ResponseWriter, r *http.Request) {
uid := r.FormValue("uid")
totpItem, _ := usermgmt.GetTOTPByUID(uid)
// Format: otpauth://totp/uid?secret=XBSWY3DPEHPK3PXP&issuer=JANUSEC
totpLink := fmt.Sprintf("otpauth://totp/%s?secret=%s&issuer=JANUSEC", uid, totpItem.TOTPKey)
var png []byte
png, err := qrcode.Encode(totpLink, qrcode.Medium, 256)
if err != nil {
utils.DebugPrintln("qrcode.Encode", err)
}
codeImageText := "data:image/png;base64," + base64.StdEncoding.EncodeToString(png)
authCodeContext := AuthCodeContext{
UID: uid,
TOTPKey: totpItem.TOTPKey,
ImageData: codeImageText,
}
if err := authCodeUITemplate.Execute(w, &authCodeContext); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
const authcodeTemplate = `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Authenticator Registration</title>
</head>
<style>
input[type=text] {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type=submit] {
width: 100%;
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
input[type=submit]:hover {
background-color: #45a045;
}
h1 {
margin: 20px auto;
text-align: center;
}
.qrcode {
display: block;
width: 256px;
height: 256px;
margin: auto;
}
div {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
width: 600px;
margin: auto;
}
a {
font-size: 12px;
margin-right: 20px;
}
.secret_key {
background-color: #D5D5D5;
text-align: center;
}
#ch:target~[data-lang-ch]:after{
content: attr(data-lang-ch);
}
[data-lang-en]:after, #en:target~[data-lang-ch]:after{
content: attr(data-lang-en);
}
</style>
<body>
<div>
<span id="ch"></span>
<span id="en"></span>
<h1 data-lang-ch="Authenticator认证码注册" data-lang-en="Authenticator Registration"></h1>
<a href="#ch">中文</a>
<a href="#en">English</a>
<hr/>
<p data-lang-ch="请使用如下任何一款手机APP扫描二维码:" data-lang-en="Please scan the qrcode with one of the following Mobile APP: "></p>
<ul>
<li>Google Authenticator</li>
<li>Microsoft Authenticator</li>
</ul>
<img src="{{ .ImageData }}" class="qrcode" />
<p data-lang-ch="或直接在APP中手工输入如下密钥:" data-lang-en="or input the following Secret Key in your mobile app:"></p>
<p class="secret_key">{{ .TOTPKey }}</p>
<hr/>
<h2 data-lang-ch="输入APP中6位认证码,完成验证" data-lang-en="Input 6-digits Code to Finish Verification"></h2>
<form action="/oauth/code/verify" method="POST">
<input type="hidden" name="uid" value="{{ .UID }}">
<input type="text" id="code" name="code" placeholder="Authenticator Code">
<input type="submit" value="Verify">
</form>
</div>
<script>
if(navigator.language=='zh-CN') window.location.hash = 'ch';
</script>
</body>
</html>`