|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
|
|
|
type passwordData struct {
|
|
|
|
Length int
|
|
|
|
Digits int
|
|
|
|
Symbols int
|
|
|
|
NoUpper bool
|
|
|
|
DenyRepeat bool
|
|
|
|
Password string
|
|
|
|
}
|
|
|
|
|
|
|
|
var d, defaults passwordData
|
|
|
|
|
|
|
|
func generatePassword(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if r.URL.Path != "/" {
|
|
|
|
http.Error(w, "404 not found.", http.StatusNotFound)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
switch r.Method {
|
|
|
|
case "GET":
|
|
|
|
d.Password, err = generate(defaults.Length, defaults.Digits, defaults.Symbols, false, false)
|
|
|
|
if err != nil {
|
|
|
|
d.Password = "Error: " + err.Error()
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
w.Write([]byte(d.Password))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.Write([]byte(d.Password))
|
|
|
|
case "POST":
|
|
|
|
if err = r.ParseForm(); err != nil {
|
|
|
|
w.WriteHeader(http.StatusUnprocessableEntity)
|
|
|
|
w.Write([]byte(fmt.Sprintf("ParseForm() err: %v", err)))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
d.Length, err = strconv.Atoi(r.FormValue("length"))
|
|
|
|
if err != nil {
|
|
|
|
d.Length = defaults.Length
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Digits, err = strconv.Atoi(r.FormValue("digits"))
|
|
|
|
if err != nil {
|
|
|
|
d.Digits = defaults.Digits
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Symbols, err = strconv.Atoi(r.FormValue("symbols"))
|
|
|
|
if err != nil {
|
|
|
|
d.Symbols = defaults.Symbols
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.FormValue("noupper") == "on" {
|
|
|
|
d.NoUpper = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.FormValue("denyrepeat") == "on" {
|
|
|
|
d.DenyRepeat = true
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Password, err = generate(d.Length, d.Digits, d.Symbols, d.NoUpper, !d.DenyRepeat)
|
|
|
|
if err != nil {
|
|
|
|
d.Password = "Error: " + err.Error()
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
w.Write([]byte(d.Password))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if d.Length == 0 {
|
|
|
|
d.Password = "Error: password can not have zero length"
|
|
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.Write([]byte(d.Password))
|
|
|
|
default:
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
w.Write([]byte("Sorry, only GET and POST methods are supported."))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkHealth(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
w.Write([]byte("Status:OK"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
|
|
// Set defaults
|
|
|
|
portPtr := flag.Int("listen", 8080, "Specify on which port to listen")
|
|
|
|
lengthPtr := flag.Int("length", 16, "Specify the password length")
|
|
|
|
digitsPtr := flag.Int("digits", 2, "Specify the the number of digits in the password")
|
|
|
|
symbolsPtr := flag.Int("symbols", 2, "Specify the the number of symbols in the password")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
defaults.Length = *lengthPtr
|
|
|
|
defaults.Digits = *digitsPtr
|
|
|
|
defaults.Symbols = *symbolsPtr
|
|
|
|
|
|
|
|
http.HandleFunc("/", generatePassword)
|
|
|
|
http.HandleFunc("/health", checkHealth)
|
|
|
|
|
|
|
|
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*portPtr), nil))
|
|
|
|
}
|