login page

This commit is contained in:
2020-12-21 18:53:42 +01:00
parent 5db5b0aeba
commit 4fc51f86e4
4 changed files with 81 additions and 6 deletions

61
src/login.go Normal file
View File

@ -0,0 +1,61 @@
package main
import (
"time"
"net/http"
"bytes"
"github.com/cornelk/hashmap"
)
type loginStruct struct {
FalsePassword bool
}
var sessions hashmap.HashMap
const sessionName string = "session"
func login(w http.ResponseWriter, r *http.Request) {
var err error
loginStruct := loginStruct{}
var login bool = false
if loggedIn(r) {
http.Redirect(w, r, "dash", http.StatusSeeOther)
return
}
if r.Method == http.MethodPost {
var username string = r.FormValue("username")
var password string = r.FormValue("password")
var hash []byte
var salt []byte
db.QueryRow("SELECT hash,salt FROM account WHERE username = ?", username).Scan(&hash, &salt)
login = bytes.Equal(hashFunc([]byte(password), salt), hash)
loginStruct.FalsePassword = !login
if login {
key, err := GenerateRandomString(64)
log(err)
cookie := http.Cookie{
Name: sessionName,
Value: key,
Expires: time.Now().Add(10 * 24 * time.Hour),
HttpOnly: true,
Secure: true,
}
http.SetCookie(w, &cookie)
sessions.Set(key, username)
http.Redirect(w, r, "dash", http.StatusSeeOther)
} else {
w.Header().Set("Content-Type", "text/html")
err = loginTmpl.Execute(w, loginStruct)
log(err)
}
} else {
w.Header().Set("Content-Type", "text/html")
loginTmpl.Execute(w, loginStruct)
log(err)
}
}
func loggedIn(r *http.Request) bool {
key, err := r.Cookie(sessionName)
if err != nil {
return false
}
_, valid := sessions.GetStringKey(key.Value)
return valid
}

View File

@ -12,7 +12,6 @@ import (
"net/http"
"os"
"regexp"
"github.com/cornelk/hashmap"
"code.gitea.io/sdk/gitea"
"fmt"
"golang.org/x/crypto/argon2"
@ -20,11 +19,11 @@ import (
var discord *discordgo.Session
var secret secrets_json
var config config_json
var cacheAccounts hashmap.HashMap
var db *sql.DB
var giteaClient *gitea.Client
var registerTmpl *template.Template
var submitTmpl *template.Template
var loginTmpl *template.Template
type account struct {
email string
username string
@ -100,10 +99,13 @@ func main() {
_ = moodle
registerTmpl = template.Must(template.ParseFiles("tmpl/register.html"))
submitTmpl = template.Must(template.ParseFiles("tmpl/submit.html"))
loginTmpl = template.Must(template.ParseFiles("tmpl/login.html"))
remail = regexp2.MustCompile("^(?=.{0,255}$)(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$", 0)
rusername = regexp.MustCompile("^([[:lower:]]|\\d|_|-|\\.){1,40}$")
rpassword = regexp2.MustCompile("^(?=.{8,255}$)(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\\W).*$", 0)
http.HandleFunc("/register", register)
http.HandleFunc("/submit", submit)
http.HandleFunc("/login", login)
http.ListenAndServe(":" + fmt.Sprint(config.Port), nil)
}
@ -113,6 +115,6 @@ func log(err error) {
}
}
func hash(password []byte, salt []byte) []byte {
func hashFunc(password []byte, salt []byte) []byte {
return argon2.IDKey(password, salt, 1, 64*1024, 4, 32)
}

View File

@ -10,7 +10,9 @@ import (
"time"
"code.gitea.io/sdk/gitea"
"crypto/rand"
"github.com/cornelk/hashmap"
)
var cacheAccounts hashmap.HashMap
var rusername *regexp.Regexp
var remail *regexp2.Regexp
var rpassword *regexp2.Regexp
@ -43,8 +45,8 @@ func register(w http.ResponseWriter, r *http.Request) {
newAccount.discordId = newRbuMember.User.ID
{
var username string
registerstruct.AlreadyEsitsInDatabase.Username = db.QueryRow("select username from account where username = ?", newAccount.username).Scan(&username) == nil || UsernameExistsInMem(newAccount.username) // check if username exits
registerstruct.AlreadyEsitsInDatabase.DiscordUsername = db.QueryRow("select username from account where discordUserId = ?", newAccount.discordId).Scan(&username) == nil || discordUsernameExistsInMem(newAccount.discordId)
registerstruct.AlreadyEsitsInDatabase.Username = db.QueryRow("SELECT username FROM account WHERE username = ?", newAccount.username).Scan(&username) == nil || UsernameExistsInMem(newAccount.username) // check if username exits
registerstruct.AlreadyEsitsInDatabase.DiscordUsername = db.QueryRow("SELECT username FROM account WHERE discordUserId = ?", newAccount.discordId).Scan(&username) == nil || discordUsernameExistsInMem(newAccount.discordId)
}
registerstruct.Success = !registerstruct.WrongAccount.User && !registerstruct.WrongAccount.Pass && !registerstruct.WrongAccount.Email && !registerstruct.WrongAccount.DiscordUser && !registerstruct.AlreadyEsitsInDatabase.DiscordUsername && !registerstruct.AlreadyEsitsInDatabase.Username
if !registerstruct.Success {
@ -76,7 +78,7 @@ func register(w http.ResponseWriter, r *http.Request) {
salt := make([]byte, 32)
_, err := rand.Read(salt)
log(err)
hash := hash([]byte(account.password), salt)
hash := hashFunc([]byte(account.password), salt)
// add user to the database
query := "INSERT INTO account(username, email, hash, salt, discordUserId) VALUES (?, ?, ?, ?, ?)"
ctx, cancelfunc := context.WithTimeout(context.Background(), 5*time.Second)

10
tmpl/login.html Normal file
View File

@ -0,0 +1,10 @@
{{if .FalsePassword}}
<p>falches Passwort</p>
{{end}}
<form method="POST" class="responsive">
<label class="responsive">Benutzername:</label><br/>
<input class="responsive" type="text" name="username"><br/>
<label class="responsive">Passwort:</label><br/>
<input class="responsive" type="password" name="password"><br/>
<input type="submit" name="login" value="login"class="btn active responsive">
</form>