Updating some of the examples.
This commit is contained in:
parent
01fd3e5886
commit
395d932f93
23
README.md
23
README.md
@ -21,16 +21,25 @@ Go library for generating and using One Time Passwords. Supports both HOTP ([RFC
|
|||||||
opts.Label = user
|
opts.Label = user
|
||||||
key := otp.NewHOTPKey(opts)
|
key := otp.NewHOTPKey(opts)
|
||||||
|
|
||||||
// Store this string variable in your database
|
|
||||||
keyURL := key.URL()
|
keyURL := key.URL()
|
||||||
|
Store(user, keyURL)
|
||||||
|
|
||||||
// Provide the URL to the customer so they can include it in their 2FA client.
|
// Provide the URL to the customer so they can include it in their 2FA client.
|
||||||
// Can email URL, or present QR code encoding of the URL
|
// Can email URL, or present QR code encoding of the URL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store this string variable in your database
|
||||||
|
func Store(user, url string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the url string variable from your database
|
||||||
|
func GetURL(user string) string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func CheckUsersCode(user string, code string) (bool, error) {
|
func CheckUsersCode(user string, code string) (bool, error) {
|
||||||
// Retrieve this string variable from your database
|
keyURL := GetURL(user)
|
||||||
var keyURL string
|
|
||||||
|
|
||||||
key, err := otp.FromURL(keyURL)
|
key, err := otp.FromURL(keyURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -38,7 +47,7 @@ Go library for generating and using One Time Passwords. Supports both HOTP ([RFC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure you are using the correct key
|
// Ensure you are using the correct key
|
||||||
if key.Label != user {
|
if key.Label() != user {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +57,11 @@ Go library for generating and using One Time Passwords. Supports both HOTP ([RFC
|
|||||||
// Don't need this step for TOTP keys as the counter is time-based
|
// Don't need this step for TOTP keys as the counter is time-based
|
||||||
keyURL = key.URL()
|
keyURL = key.URL()
|
||||||
|
|
||||||
|
return success, nil
|
||||||
return success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### OTP Client
|
### OTP Client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -85,7 +94,7 @@ Go library for generating and using One Time Passwords. Supports both HOTP ([RFC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify Issuer and Label are correct
|
// Verify Issuer and Label are correct
|
||||||
if key.Issuer != issuer || key.Label != username {
|
if key.Issuer() != issuer || key.Label() != username {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
58
hotp_client_example_test.go
Normal file
58
hotp_client_example_test.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package otp_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"dev.justinjudd.org/justin/otp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Just an example for storing OTP keys on the client
|
||||||
|
var keys map[Key]string
|
||||||
|
|
||||||
|
// Key is used as keys for the otp key storing map
|
||||||
|
type Key struct {
|
||||||
|
Issuer, Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCode(issuer, username string) (string, error) {
|
||||||
|
|
||||||
|
mapKey := Key{issuer, username}
|
||||||
|
|
||||||
|
// Get the stored Key URL
|
||||||
|
keyURL, ok := keys[mapKey]
|
||||||
|
if !ok {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the key from the URL
|
||||||
|
key, err := otp.FromURL(keyURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify Issuer and Label are correct
|
||||||
|
if key.Issuer() != issuer || key.Label() != username {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
code := key.OTP()
|
||||||
|
|
||||||
|
// If using HOTP, than need to save the state
|
||||||
|
keyURL = key.URL()
|
||||||
|
keys[mapKey] = keyURL
|
||||||
|
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_hOTPClient() {
|
||||||
|
issuer := "example.com"
|
||||||
|
username := "username"
|
||||||
|
|
||||||
|
code, err := GetCode(issuer, username)
|
||||||
|
if err != nil {
|
||||||
|
// Handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present code to user, or send code to server
|
||||||
|
fmt.Println(code)
|
||||||
|
}
|
@ -6,15 +6,15 @@ import (
|
|||||||
"dev.justinjudd.org/justin/otp"
|
"dev.justinjudd.org/justin/otp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Key struct {
|
type MapKey struct {
|
||||||
Issuer, Label string
|
Issuer, Label string
|
||||||
}
|
}
|
||||||
|
|
||||||
var keys map[Key]string
|
var keysMap map[MapKey]string
|
||||||
|
|
||||||
func CreateKey(issuer, username string) error {
|
func CreateKey(issuer, username string) error {
|
||||||
mapKey := Key{issuer, username}
|
mapKey := MapKey{issuer, username}
|
||||||
_, ok := keys[mapKey]
|
_, ok := keysMap[mapKey]
|
||||||
if ok {
|
if ok {
|
||||||
return fmt.Errorf("Key already exists for Issuer:%s, Label:%s", issuer, username)
|
return fmt.Errorf("Key already exists for Issuer:%s, Label:%s", issuer, username)
|
||||||
}
|
}
|
||||||
@ -23,14 +23,14 @@ func CreateKey(issuer, username string) error {
|
|||||||
opts.Label = username
|
opts.Label = username
|
||||||
k := otp.NewHOTPKey(opts)
|
k := otp.NewHOTPKey(opts)
|
||||||
|
|
||||||
keys[mapKey] = k.URL()
|
keysMap[mapKey] = k.URL()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckCode(issuer, username, code string) bool {
|
func CheckCode(issuer, username, code string) bool {
|
||||||
mapKey := Key{issuer, username}
|
mapKey := MapKey{issuer, username}
|
||||||
keyURL, ok := keys[mapKey]
|
keyURL, ok := keysMap[mapKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
78
hotp_server_example_test.go
Normal file
78
hotp_server_example_test.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package otp_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"dev.justinjudd.org/justin/otp"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Issuer = "example.com"
|
||||||
|
|
||||||
|
func CreateKeyForUser(user string) {
|
||||||
|
|
||||||
|
opts := otp.NewHOTPKeyOptions()
|
||||||
|
opts.Issuer = Issuer
|
||||||
|
opts.Label = user
|
||||||
|
key := otp.NewHOTPKey(opts)
|
||||||
|
|
||||||
|
keyURL := key.URL()
|
||||||
|
Store(user, keyURL)
|
||||||
|
|
||||||
|
// Provide the URL to the customer so they can include it in their 2FA client.
|
||||||
|
// Can email URL, or present QR code encoding of the URL
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store this string variable in your database
|
||||||
|
func Store(user, url string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the url string variable from your database
|
||||||
|
func GetURL(user string) string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the OTP code from the user
|
||||||
|
func getCode() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckUsersCode(user string, code string) (bool, error) {
|
||||||
|
keyURL := GetURL(user)
|
||||||
|
|
||||||
|
key, err := otp.FromURL(keyURL)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure you are using the correct key
|
||||||
|
if key.Label() != user {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
success := key.Verify(code)
|
||||||
|
|
||||||
|
// Counter has been updated, update this info in the database
|
||||||
|
// Don't need this step for TOTP keys as the counter is time-based
|
||||||
|
keyURL = key.URL()
|
||||||
|
|
||||||
|
return success, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_hOTPServer() {
|
||||||
|
|
||||||
|
// Create new user
|
||||||
|
user := "username"
|
||||||
|
CreateKeyForUser(user)
|
||||||
|
|
||||||
|
// When user is authenticating
|
||||||
|
// Perform password based auth - if that is successful, then continue
|
||||||
|
code := getCode()
|
||||||
|
success, err := CheckUsersCode(user, code)
|
||||||
|
if err != nil {
|
||||||
|
// Handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
if success {
|
||||||
|
// User is authenticated
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user