aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-09 16:46:26 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-09 16:46:26 +0100
commitebb7553cc87b5a2504edc8e06ee12375fd925029 (patch)
tree83b17cb90ed9e631a8056a26e6a09334a747e68f
parent3fe43f85aefedc6223aee45171df483e2f57c381 (diff)
downloadguichet-ebb7553cc87b5a2504edc8e06ee12375fd925029.tar.gz
guichet-ebb7553cc87b5a2504edc8e06ee12375fd925029.zip
Implement logout
-rw-r--r--main.go119
-rw-r--r--static/css/main.css6
-rw-r--r--templates/home.html15
-rw-r--r--templates/layout.html10
-rw-r--r--templates/login.html21
5 files changed, 112 insertions, 59 deletions
diff --git a/main.go b/main.go
index ddd6552..a58b2a1 100644
--- a/main.go
+++ b/main.go
@@ -1,28 +1,28 @@
package main
import (
- "os"
- "strings"
- "flag"
- "log"
- "net/http"
- "io/ioutil"
- "encoding/json"
- "encoding/base64"
"crypto/rand"
"crypto/tls"
+ "encoding/base64"
+ "encoding/json"
+ "flag"
"html/template"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "os"
+ "strings"
- "github.com/gorilla/sessions"
"github.com/go-ldap/ldap/v3"
+ "github.com/gorilla/sessions"
)
type ConfigFile struct {
HttpBindAddr string `json:"http_bind_addr"`
SessionKey string `json:"session_key"`
LdapServerAddr string `json:"ldap_server_addr"`
- LdapTLS bool `json:"ldap_tls"`
- UserFormat string `json:"user_format"`
+ LdapTLS bool `json:"ldap_tls"`
+ UserFormat string `json:"user_format"`
}
var configFlag = flag.String("config", "./config.json", "Configuration file path")
@@ -30,12 +30,13 @@ var configFlag = flag.String("config", "./config.json", "Configuration file path
var config *ConfigFile
const SESSION_NAME = "guichet_session"
-var store *sessions.CookieStore = nil
-func readConfig() ConfigFile{
+var store sessions.Store = nil
+
+func readConfig() ConfigFile {
key_bytes := make([]byte, 32)
n, err := rand.Read(key_bytes)
- if err!= nil || n != 32 {
+ if err != nil || n != 32 {
log.Fatal(err)
}
@@ -43,8 +44,8 @@ func readConfig() ConfigFile{
HttpBindAddr: ":9991",
SessionKey: base64.StdEncoding.EncodeToString(key_bytes),
LdapServerAddr: "ldap://127.0.0.1:389",
- LdapTLS: false,
- UserFormat: "cn=%s,ou=users,dc=example,dc=com",
+ LdapTLS: false,
+ UserFormat: "cn=%s,ou=users,dc=example,dc=com",
}
_, err = os.Stat(*configFlag)
@@ -87,9 +88,10 @@ func main() {
config_file := readConfig()
config = &config_file
- store = sessions.NewCookieStore([]byte(config.SessionKey))
+ store = sessions.NewFilesystemStore("", []byte(config.SessionKey))
http.HandleFunc("/", handleHome)
+ http.HandleFunc("/logout", handleLogout)
staticfiles := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", staticfiles))
@@ -102,9 +104,9 @@ func main() {
type LoginInfo struct {
Username string
- DN string
+ DN string
Password string
- }
+}
func logRequest(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -115,17 +117,23 @@ func logRequest(handler http.Handler) http.Handler {
func checkLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
session, err := store.Get(r, SESSION_NAME)
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return nil
- }
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return nil
+ }
- login_info, has_login_info := session.Values["login_info"]
- if !has_login_info {
+ username, ok := session.Values["login_username"]
+ password, ok2 := session.Values["login_password"]
+ user_dn, ok3 := session.Values["login_dn"]
+ if !(ok && ok2 && ok3) {
return handleLogin(w, r)
}
- return login_info.(*LoginInfo)
+ return &LoginInfo{
+ DN: user_dn.(string),
+ Username: username.(string),
+ Password: password.(string),
+ }
}
func ldapOpen(w http.ResponseWriter) *ldap.Conn {
@@ -149,18 +157,15 @@ func ldapOpen(w http.ResponseWriter) *ldap.Conn {
// Templates ----
type LoginFormData struct {
- Username string
+ Username string
ErrorMessage string
}
-var (
- templateLogin = template.Must(template.ParseFiles("templates/layout.html", "templates/login.html"))
- templateHome = template.Must(template.ParseFiles("templates/layout.html", "templates/home.html"))
-)
-
// Page handlers ----
func handleHome(w http.ResponseWriter, r *http.Request) {
+ templateHome := template.Must(template.ParseFiles("templates/layout.html", "templates/home.html"))
+
login := checkLogin(w, r)
if login == nil {
return
@@ -169,7 +174,29 @@ func handleHome(w http.ResponseWriter, r *http.Request) {
templateHome.Execute(w, login)
}
+func handleLogout(w http.ResponseWriter, r *http.Request) {
+ session, err := store.Get(r, SESSION_NAME)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ delete(session.Values, "login_username")
+ delete(session.Values, "login_password")
+ delete(session.Values, "login_dn")
+
+ err = session.Save(r, w)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ http.Redirect(w, r, "/", http.StatusFound)
+}
+
func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
+ templateLogin := template.Must(template.ParseFiles("templates/layout.html", "templates/login.html"))
+
if r.Method == "GET" {
templateLogin.Execute(w, LoginFormData{})
return nil
@@ -177,23 +204,18 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
r.ParseForm()
username := strings.Join(r.Form["username"], "")
+ password := strings.Join(r.Form["password"], "")
user_dn := strings.ReplaceAll(config.UserFormat, "%s", username)
- login_info := &LoginInfo{
- DN: user_dn,
- Username: username,
- Password: strings.Join(r.Form["password"], ""),
- }
-
l := ldapOpen(w)
if l == nil {
return nil
}
- err := l.Bind(user_dn, login_info.Password)
+ err := l.Bind(user_dn, password)
if err != nil {
templateLogin.Execute(w, LoginFormData{
- Username: username,
+ Username: username,
ErrorMessage: err.Error(),
})
return nil
@@ -206,8 +228,21 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
return nil
}
- session.Values["login_info"] = login_info
- return login_info
+ session.Values["login_username"] = username
+ session.Values["login_password"] = password
+ session.Values["login_dn"] = user_dn
+
+ err = session.Save(r, w)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return nil
+ }
+
+ return &LoginInfo{
+ DN: user_dn,
+ Username: username,
+ Password: password,
+ }
} else {
http.Error(w, "Unsupported method", http.StatusBadRequest)
return nil
diff --git a/static/css/main.css b/static/css/main.css
deleted file mode 100644
index 057814d..0000000
--- a/static/css/main.css
+++ /dev/null
@@ -1,6 +0,0 @@
-#contents {
- width: 800px;
- margin: auto;
- margin-top: 16px;
-}
-
diff --git a/templates/home.html b/templates/home.html
index 0b39e11..6a11af3 100644
--- a/templates/home.html
+++ b/templates/home.html
@@ -1,7 +1,18 @@
{{define "title"}}Guichet{{end}}
{{define "body"}}
-<h1>Guichet</h1>
+<div class="alert alert-success">
+ Bienvenue, <strong>{{ .Username }}</strong> !
+</div>
+
+<div class="card">
+ <div class="card-header">
+ Gérer mon compte
+ </div>
+ <div class="list-group list-group-flush">
+ <a class="list-group-item list-group-item-action" href="/">Test</a>
+ <a class="list-group-item list-group-item-action" href="/logout">Se déconnecter</a>
+ </div>
+</div>
-Welcome, {{ .Username }}!
{{end}}
diff --git a/templates/layout.html b/templates/layout.html
index 28cd262..5f4a315 100644
--- a/templates/layout.html
+++ b/templates/layout.html
@@ -2,12 +2,16 @@
<html>
<head>
<meta charset="utf-8">
- <title>{{template "title"}}</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
- <link rel="stylesheet" href="/static/css/main.css">
+
+ <title>{{template "title"}} Guichet</title>
</head>
<body>
- <div id="contents">
+ <div class="container">
+ <h1>Guichet Deuxfleurs💮💮</h1>
+ <hr />
{{template "body" .}}
</div>
</body>
diff --git a/templates/login.html b/templates/login.html
index 80642ea..0801884 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -1,12 +1,21 @@
-{{define "title"}}Log in{{end}}
+{{define "title"}}{{end}}
{{define "body"}}
-<h1>Log in</h1>
<form method="POST">
- <div>{{ .ErrorMessage }}</div>
- Username: <input type="text" name="username" value="{{ .Username }}" /><br />
- Password: <input type="password" name="password" /><br />
- <input type="submit" value="log in">
+ {{if .ErrorMessage}}
+ <div class="alert alert-danger">Impossible de se connecter.
+ <div style="font-size: 0.8em">{{ .ErrorMessage }}</div>
+ </div>
+ {{end}}
+ <div class="form-group">
+ <label for="username">Nom d'utilisateur:</label>
+ <input type="text" name="username" id="username" class="form-control" value="{{ .Username }}" />
+ </div>
+ <div class="form-group">
+ <label for="password">Mot de passe:</label>
+ <input type="password" name="password" id="password" class="form-control" />
+ </div>
+ <button type="submit" class="btn btn-primary">Se connecter</button>
</form>
{{end}}