commit 31549f07b048a85605ae385ff4acc6a2ee50c198
parent 987ce0e960e1ae7032e66981d4630114cb3f27ae
Author: Peter Kosyh <p.kosyh@gmail.com>
Date: Thu, 3 Sep 2020 17:02:36 +0300
auth draft
Diffstat:
4 files changed, 89 insertions(+), 21 deletions(-)
diff --git a/ii-node/main.go b/ii-node/main.go
@@ -55,8 +55,6 @@ var verbose_opt *bool = flag.Bool("v", false, "Verbose")
type WWW struct {
tpl *template.Template
db *ii.DB
- w http.ResponseWriter
- r *http.Request
}
func main() {
diff --git a/ii-node/tpl/login.tpl b/ii-node/tpl/login.tpl
@@ -0,0 +1,6 @@
+{{template "header.tpl"}}
+<form method="post" enctype="multipart/form-data" action="/login">
+<input type="text" name="username" class="login" placeholder="username"><br>
+<input type="password" name="password" class="passwd" placeholder="password"><br>
+<button class="form-button">Login</button>
+{{template "footer.tpl"}}
diff --git a/ii-node/web.go b/ii-node/web.go
@@ -22,7 +22,37 @@ type WebContext struct {
BasePath string
}
-func www_index(www WWW, w http.ResponseWriter, r *http.Request) error {
+func www_login(user *ii.User, www WWW, w http.ResponseWriter, r *http.Request) error {
+ var ctx WebContext
+ ii.Trace.Printf("www login")
+ switch r.Method {
+ case "GET":
+ err := www.tpl.ExecuteTemplate(w, "login.tpl", ctx)
+ return err
+ case "POST":
+ if err := r.ParseForm(); err != nil {
+ ii.Error.Printf("Error in POST request: %s", err)
+ return err
+ }
+ user := r.FormValue("username")
+ password := r.FormValue("password")
+ udb := ii.LoadUsers(*users_opt)
+ if udb == nil || !udb.Auth(user, password) {
+ ii.Info.Printf("Access denied for user: %s", user)
+ return nil
+ }
+ exp := time.Now().Add(10 * 365 * 24 * time.Hour)
+ cookie := http.Cookie{Name: "pauth", Value: udb.Secret(user), Expires: exp}
+ http.SetCookie(w, &cookie)
+ ii.Info.Printf("User logged in: %s:%s\n", user, password)
+ http.Redirect(w, r, "/", http.StatusSeeOther)
+ default:
+ return nil
+ }
+ return nil
+}
+
+func www_index(user *ii.User, www WWW, w http.ResponseWriter, r *http.Request) error {
var ctx WebContext
ii.Trace.Printf("www index")
@@ -105,7 +135,7 @@ func makePager(ctx *WebContext, count int, page int) int {
return start
}
-func www_topics(www WWW, w http.ResponseWriter, r *http.Request, echo string, page int) error {
+func www_topics(user *ii.User, www WWW, w http.ResponseWriter, r *http.Request, echo string, page int) error {
db := www.db
var ctx WebContext
@@ -153,14 +183,7 @@ func www_topics(www WWW, w http.ResponseWriter, r *http.Request, echo string, pa
return err
}
-func msg_format(txt string) template.HTML {
- txt = strings.Replace(txt, "&", "&", -1)
- txt = strings.Replace(txt, "<", "<", -1)
- txt = strings.Replace(txt, ">", ">", -1)
- return template.HTML(strings.Replace(txt, "\n", "<br/>", -1))
-}
-
-func www_topic(www WWW, w http.ResponseWriter, r *http.Request, id string, page int) error {
+func www_topic(user *ii.User, www WWW, w http.ResponseWriter, r *http.Request, id string, page int) error {
db := www.db
var ctx WebContext
@@ -189,6 +212,13 @@ func www_topic(www WWW, w http.ResponseWriter, r *http.Request, id string, page
return err
}
+func msg_format(txt string) template.HTML {
+ txt = strings.Replace(txt, "&", "&", -1)
+ txt = strings.Replace(txt, "<", "<", -1)
+ txt = strings.Replace(txt, ">", ">", -1)
+ return template.HTML(strings.Replace(txt, "\n", "<br/>", -1))
+}
+
func WebInit(www *WWW, db *ii.DB) {
funcMap := template.FuncMap{
"fdate": func (date int64) string {
@@ -201,24 +231,36 @@ func WebInit(www *WWW, db *ii.DB) {
}
func handleWWW(www WWW, w http.ResponseWriter, r *http.Request) error {
+ var user *ii.User
+ cookie, err := r.Cookie("pauth")
+ if err == nil {
+ udb := ii.LoadUsers(*users_opt) /* per each request */
+ if udb.Access(cookie.Value) {
+ user = udb.UserInfo(cookie.Value)
+ ii.Info.Printf("User: %s GET %s", user.Name, r.URL.Path)
+ }
+ }
path := strings.TrimPrefix(r.URL.Path, "/")
args := strings.Split(path, "/")
if path == "" {
- return www_index(www, w, r)
+ return www_index(user, www, w, r)
+ } else if path == "login" {
+ return www_login(user, www, w, r)
} else if ii.IsMsgId(args[0]) {
page := 1
if len(args) > 1 {
fmt.Sscanf(args[1], "%d", &page)
}
- return www_topic(www, w, r, args[0], page)
+ return www_topic(user, www, w, r, args[0], page)
} else if ii.IsEcho(args[0]) {
page := 1
if len(args) > 1 {
fmt.Sscanf(args[1], "%d", &page)
}
- return www_topics(www, w, r, args[0], page)
+ return www_topics(user, www, w, r, args[0], page)
} else {
w.WriteHeader(http.StatusNotFound)
+ fmt.Fprintf(w, "404\n")
}
return nil
}
diff --git a/ii/db.go b/ii/db.go
@@ -36,11 +36,6 @@ type DB struct {
Name string
}
-func mkdir(path string) {
- if _, err := os.Stat(path); os.IsNotExist(err) {
- }
-}
-
func append_file(fn string, text string) error {
f, err := os.OpenFile(fn, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
@@ -453,7 +448,7 @@ func (db *DB) Echoes(names []string) []Echo {
list = append(list, v)
}
sort.SliceStable(list, func(i, j int) bool {
- return list[i].Last.Off > list[j].Last.Off
+ return list[i].Last.Off < list[j].Last.Off
})
}
return list
@@ -604,6 +599,22 @@ func MakeSecret(msg string) string {
return s[0:10]
}
+func (db *UDB) Secret(User string) string {
+ ui, ok := db.Names[User]
+ if !ok {
+ return ""
+ }
+ return ui.Secret
+}
+
+func (db *UDB) Auth(User string, Passwd string) bool {
+ ui, ok := db.Names[User]
+ if !ok {
+ return false
+ }
+ return ui.Secret == MakeSecret(User + Passwd)
+}
+
func (db *UDB) Access(Secret string) bool {
_, ok := db.Secrets[Secret]
return ok
@@ -618,6 +629,16 @@ func (db *UDB) Name(Secret string) string {
return ""
}
+func (db *UDB) UserInfo(Secret string) *User {
+ name, ok := db.Secrets[Secret]
+ if ok {
+ v := db.Names[name]
+ return &v
+ }
+ Error.Printf("No user for secret: %s", Secret)
+ return nil
+}
+
func (db *UDB) Id(Secret string) int32 {
name, ok := db.Secrets[Secret]
if ok {
@@ -694,6 +715,7 @@ func LoadUsers(path string) *UDB {
return true
})
if err != nil {
+ Error.Printf("Can not read user DB: %s", err)
return nil
}
return &db