commit 1f052c23bbceb23ae1b2face4d28f61131238303
parent 84d07159093479b18cad7c9e1657d981db9e5787
Author: Peter Kosyh <p.kosyh@gmail.com>
Date: Mon, 7 Sep 2020 12:20:08 +0300
udb refactoring
Diffstat:
4 files changed, 92 insertions(+), 25 deletions(-)
diff --git a/ii-node/main.go b/ii-node/main.go
@@ -20,8 +20,9 @@ func open_db(path string) *ii.DB {
return db
}
-func PointMsg(db *ii.DB, pauth string, tmsg string) string {
- udb := ii.LoadUsers(*users_opt)
+func PointMsg(db *ii.DB, udb *ii.UDB, pauth string, tmsg string) string {
+ udb.LoadUsers()
+
if !udb.Access(pauth) {
ii.Info.Printf("Access denied for pauth: %s", pauth)
return "Access denied"
@@ -59,16 +60,18 @@ type WWW struct {
tpl *template.Template
db *ii.DB
edb *ii.EDB
+ udb *ii.UDB
}
func main() {
var www WWW
ii.OpenLog(ioutil.Discard, os.Stdout, os.Stderr)
+ flag.Parse()
+
db := open_db(*db_opt)
edb := ii.LoadEcholist(*echo_opt)
-
- flag.Parse()
+ udb := ii.OpenUsers(*users_opt)
if *verbose_opt {
ii.OpenLog(os.Stdout, os.Stdout, os.Stderr)
}
@@ -76,6 +79,7 @@ func main() {
db.Name = *sysname_opt
www.db = db
www.edb = edb
+ www.udb = udb
www.Host = *host_opt
WebInit(&www)
@@ -111,7 +115,7 @@ func main() {
return
}
ii.Info.Printf("/u/point/%s/%s GET request", pauth, tmsg)
- fmt.Fprintf(w, PointMsg(db, pauth, tmsg))
+ fmt.Fprintf(w, PointMsg(db, udb, pauth, tmsg))
})
http.HandleFunc("/u/point", func(w http.ResponseWriter, r *http.Request) {
var pauth, tmsg string
@@ -127,7 +131,7 @@ func main() {
return
}
ii.Info.Printf("/u/point/%s/%s POST request", pauth, tmsg)
- fmt.Fprintf(w, PointMsg(db, pauth, tmsg))
+ fmt.Fprintf(w, PointMsg(db, udb, pauth, tmsg))
})
http.HandleFunc("/x/c/", func(w http.ResponseWriter, r *http.Request) {
enames := strings.Split(r.URL.Path[5:], "/")
diff --git a/ii-node/web.go b/ii-node/web.go
@@ -51,7 +51,7 @@ func www_register(ctx *WebContext, w http.ResponseWriter, r *http.Request) error
password := r.FormValue("password")
email := r.FormValue("email")
- udb := ii.LoadUsers(*users_opt)
+ udb := ctx.www.udb
err := udb.Add(user, email, password)
if err != nil {
ii.Info.Printf("Can not register user %s: %s", user, err)
@@ -78,8 +78,8 @@ func www_login(ctx *WebContext, w http.ResponseWriter, r *http.Request) error {
}
user := r.FormValue("username")
password := r.FormValue("password")
- udb := ii.LoadUsers(*users_opt)
- if udb == nil || !udb.Auth(user, password) {
+ udb := ctx.www.udb
+ if !udb.Auth(user, password) {
ii.Info.Printf("Access denied for user: %s", user)
return errors.New("Access denied")
}
@@ -123,6 +123,20 @@ func www_index(ctx *WebContext, w http.ResponseWriter, r *http.Request) error {
return err
}
+func www_avatar(ctx *WebContext, w http.ResponseWriter, r *http.Request, user string) error {
+ // udb := ctx.www.udb
+ // u := udb.UserInfo(udb.Name(user))
+ // ava, _ := u.Tags.Get("avatar")
+ // if ava == "" {
+ // return nil
+ // }
+ // if data, err := base64.StdEncoding.DecodeString(ava); err != nil {
+ // txt := msg_clean(string(data))
+ // lines := strings.Split(txt, "\n")
+ // }
+ return nil
+}
+
type Topic struct {
Ids []string
Count int
@@ -220,7 +234,6 @@ func www_topics(ctx *WebContext, w http.ResponseWriter, r *http.Request, page i
db := ctx.www.db
echo := ctx.BasePath
ctx.Echo = echo
-
mis := db.LookupIDS(db.SelectIDS(ii.Query{Echo: echo}))
ii.Trace.Printf("www topics: %s", echo)
topicsIds := db.GetTopics(mis)
@@ -640,6 +653,7 @@ func handleWWW(www *WWW, w http.ResponseWriter, r *http.Request) {
var user *ii.User = &ii.User{}
ctx.User = user
ctx.www = www
+ www.udb.LoadUsers()
err := _handleWWW(&ctx, w, r)
if err != nil {
handleErr(&ctx, w, err)
@@ -649,7 +663,7 @@ func handleWWW(www *WWW, w http.ResponseWriter, r *http.Request) {
func _handleWWW(ctx *WebContext, w http.ResponseWriter, r *http.Request) error {
cookie, err := r.Cookie("pauth")
if err == nil {
- udb := ii.LoadUsers(*users_opt) /* per each request */
+ udb := ctx.www.udb
if udb.Access(cookie.Value) {
if user := udb.UserInfo(cookie.Value); user != nil {
ctx.User = user
@@ -676,6 +690,12 @@ func _handleWWW(ctx *WebContext, w http.ResponseWriter, r *http.Request) error {
} else if path == "register" {
ctx.BasePath = "register"
return www_register(ctx, w, r)
+ } else if path == "avatar" {
+ ctx.BasePath = "avatar"
+ if len(args) < 2 {
+ return errors.New("Wrong request")
+ }
+ return www_avatar(ctx, w, r, args[1])
} else if ii.IsMsgId(args[0]) {
page := 0
if len(args) > 1 {
diff --git a/ii/db.go b/ii/db.go
@@ -657,7 +657,8 @@ type UDB struct {
Names map[string]User
Secrets map[string]string
List []string
- Sync sync.Mutex
+ Sync sync.RWMutex
+ FileSize int64
}
func IsUsername(u string) bool {
@@ -678,6 +679,8 @@ func MakeSecret(msg string) string {
}
func (db *UDB) Secret(User string) string {
+ db.Sync.RLock()
+ defer db.Sync.RUnlock()
ui, ok := db.Names[User]
if !ok {
return ""
@@ -686,6 +689,8 @@ func (db *UDB) Secret(User string) string {
}
func (db *UDB) Auth(User string, Passwd string) bool {
+ db.Sync.RLock()
+ defer db.Sync.RUnlock()
ui, ok := db.Names[User]
if !ok {
return false
@@ -694,11 +699,15 @@ func (db *UDB) Auth(User string, Passwd string) bool {
}
func (db *UDB) Access(Secret string) bool {
+ db.Sync.RLock()
+ defer db.Sync.RUnlock()
_, ok := db.Secrets[Secret]
return ok
}
func (db *UDB) Name(Secret string) string {
+ db.Sync.RLock()
+ defer db.Sync.RUnlock()
name, ok := db.Secrets[Secret]
if ok {
return name
@@ -708,6 +717,8 @@ func (db *UDB) Name(Secret string) string {
}
func (db *UDB) UserInfo(Secret string) *User {
+ db.Sync.RLock()
+ defer db.Sync.RUnlock()
name, ok := db.Secrets[Secret]
if ok {
v := db.Names[name]
@@ -718,6 +729,8 @@ func (db *UDB) UserInfo(Secret string) *User {
}
func (db *UDB) Id(Secret string) int32 {
+ db.Sync.RLock()
+ defer db.Sync.RUnlock()
name, ok := db.Secrets[Secret]
if ok {
v, ok := db.Names[name]
@@ -768,12 +781,37 @@ func (db *UDB) Add(Name string, Mail string, Passwd string) error {
return nil
}
-func LoadUsers(path string) *UDB {
+func OpenUsers(path string) *UDB {
var db UDB
db.Path = path
+ return &db
+}
+
+func (db *UDB) LoadUsers() error {
+ db.Sync.Lock()
+ defer db.Sync.Unlock()
+ var fsize int64
+ file, err := os.Open(db.Path)
+ if err == nil {
+ info, err := file.Stat()
+ file.Close()
+ if err != nil {
+ Error.Printf("Can not stat %s file: %s", db.Path, err)
+ return err
+ }
+ fsize = info.Size()
+ } else if os.IsNotExist(err) {
+ fsize = 0
+ } else {
+ Error.Printf("Can not open %s file: %s", db.Path, err)
+ return err
+ }
+ if db.FileSize == fsize {
+ return nil
+ }
db.Names = make(map[string]User)
db.Secrets = make(map[string]string)
- err := file_lines(path, func(line string) bool {
+ err = file_lines(db.Path, func(line string) bool {
a := strings.Split(line, ":")
if len(a) < 4 {
Error.Printf("Wrong entry in user DB: %s", line)
@@ -797,16 +835,16 @@ func LoadUsers(path string) *UDB {
})
if err != nil {
Error.Printf("Can not read user DB: %s", err)
- return nil
+ return errors.New(err.Error())
}
- return &db
+ db.FileSize = fsize
+ return nil
}
type EDB struct {
Info map[string]string
List []string
Path string
- Sync sync.Mutex
}
func (db *EDB) Allowed(name string) bool {
@@ -822,6 +860,7 @@ func LoadEcholist(path string) *EDB {
var db EDB
db.Path = path
db.Info = make(map[string]string)
+
err := file_lines(path, func(line string) bool {
a := strings.SplitN(line, ":", 3)
if len(a) < 2 {
diff --git a/ii/msg.go b/ii/msg.go
@@ -177,6 +177,17 @@ func NewTags(str string) Tags {
return t
}
+func (t *Tags) Get(n string) (string, bool) {
+ if t == nil || t.Hash == nil {
+ return "", false
+ }
+ v, ok := t.Hash[n]
+ if ok {
+ return v, true
+ }
+ return "", false
+}
+
func (t *Tags) Add(str string) error {
tags := strings.Split(str, "/")
if len(tags)%2 != 0 {
@@ -212,14 +223,7 @@ func (m *Msg) Dump() string {
}
func (m *Msg) Tag(n string) (string, bool) {
- if m == nil || m.Tags.Hash == nil {
- return "", false
- }
- v, ok := m.Tags.Hash[n]
- if ok {
- return v, true
- }
- return "", false
+ return m.Tags.Get(n)
}
func (m *Msg) String() string {