Skip to content

Commit

Permalink
adds basic stat counters for users and messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ivarprudnikov committed Apr 25, 2024
1 parent a99e763 commit 420619a
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 4 deletions.
4 changes: 4 additions & 0 deletions cypress/e2e/stats.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ describe('stats spec', () => {
})

cy.contains('h1', 'Stats').should('be.visible')

cy.contains('li', 'Registered accounts').should('be.visible')
cy.contains('li', 'Active messages').should('be.visible')

})
})
9 changes: 9 additions & 0 deletions internal/storage/memstore/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ func NewMemMessageStore(salt string) storage.MessageStore {
return &memMessageStore{messages: sync.Map{}, salt: salt}
}

func (s *memMessageStore) CountMessages() (int64, error) {
var count int64
s.messages.Range(func(k, v any) bool {
count++
return true
})
return count, nil
}

func (s *memMessageStore) Encrypt(text string, pass string) (string, error) {
// derive a key from the pass
key, err := storage.StrongKey(pass, s.salt)
Expand Down
9 changes: 9 additions & 0 deletions internal/storage/memstore/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ func NewMemUserStore(salt string) storage.UserStore {
return &memUserStore{users: sync.Map{}, salt: salt}
}

func (u *memUserStore) CountUsers() (int64, error) {
var count int64
u.users.Range(func(k, v any) bool {
count++
return true
})
return count, nil
}

func (u *memUserStore) AddUser(username string, password string, permissions []string) (*storage.User, error) {
if _, ok := u.users.Load(username); ok {
return nil, errors.New("username is not available")
Expand Down
1 change: 1 addition & 0 deletions internal/storage/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
const MAX_PIN_ATTEMPTS = 5

type MessageStore interface {
CountMessages() (int64, error)
ListMessages(username string) ([]*Message, error)
AddMessage(text string, username string) (*Message, error)
GetMessage(id string) (*Message, error)
Expand Down
1 change: 1 addition & 0 deletions internal/storage/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
const PERMISSION_READ_STATS = "read:stats"

type UserStore interface {
CountUsers() (int64, error)
AddUser(username string, password string, permissions []string) (*User, error)
GetUser(username string) (*User, error)
GetUserWithPass(username string, password string) (*User, error)
Expand Down
19 changes: 16 additions & 3 deletions routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func AddRoutes(
mux.Handle("GET /messages/new", preReq(hasAuth(createMsgPageHandler(sessions))))
mux.Handle("GET /messages/{id}", preReq(showMsgHandler(sessions, messages)))
mux.Handle("POST /messages/{id}", preReq(showMsgFullHandler(sessions, messages)))
mux.Handle("GET /stats", preReq(hasAuth(hasPermission(storage.PERMISSION_READ_STATS, statsHandler(sessions)))))
mux.Handle("GET /stats", preReq(hasAuth(hasPermission(storage.PERMISSION_READ_STATS, statsHandler(sessions, users, messages)))))
mux.Handle("GET /", indexPageHandler(sessions))
}

Expand Down Expand Up @@ -310,11 +310,24 @@ func showMsgFullHandler(sessions *sessions.CookieStore, store storage.MessageSto
}
}

func statsHandler(sessions *sessions.CookieStore) http.HandlerFunc {
func statsHandler(sessions *sessions.CookieStore, userStore storage.UserStore, messageStore storage.MessageStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
sess, _ := sessions.Get(r, SESS_COOKIE)
users, err := userStore.CountUsers()
if err != nil {
sendError(r.Context(), sess, w, "failed to get a user count", err)
return
}
messages, err := messageStore.CountMessages()
if err != nil {
sendError(r.Context(), sess, w, "failed to get a message count", err)
return
}
tmpl.ExecuteTemplate(w, "stats.tmpl", map[string]interface{}{
VIEW_DATA_KEY: nil,
VIEW_DATA_KEY: map[string]int64{
"TotalUsers": users,
"TotalMessages": messages,
},
VIEW_SESS_KEY: sess.Values,
})
}
Expand Down
5 changes: 4 additions & 1 deletion web/stats.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

<h1>Stats</h1>

<p>Coming soon ...</p>
<ul>
<li>Registered accounts: {{ .data.TotalUsers }}</li>
<li>Active messages: {{ .data.TotalMessages }}</li>
</ul>

{{template "footer.tmpl" .}}
</div>
Expand Down

0 comments on commit 420619a

Please sign in to comment.