Skip to content

Commit

Permalink
feat: User authentication, init local user storage in server
Browse files Browse the repository at this point in the history
  • Loading branch information
jstnf committed Apr 29, 2024
1 parent 1b8d8f8 commit 39ea215
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
24 changes: 16 additions & 8 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ type ButtonState struct {
type Server struct {
listenAddr string
Store data.Storage
Users data.UserStorage
state *ButtonState
}

func NewAPIServer(listenAddr string, storage data.Storage) *Server {
func NewAPIServer(listenAddr string, storage data.Storage, users data.UserStorage) *Server {
return &Server{
listenAddr: listenAddr,
Store: storage,
Users: users,
state: nil,
}
}
Expand Down Expand Up @@ -76,21 +78,25 @@ func (s *Server) handlePostPress(c *gin.Context) {
return
}

// TODO authentication
user, err := s.Users.GetUserById(body.UserId)
if err != nil {
c.JSON(http.StatusBadRequest, PressErrorResponse{Error: data.ErrorUserUnknown})
return
}

// Get last press in general - if it's from the same user, return an error
lastPress, err := s.Store.GetLastPress()
if err != nil {
c.JSON(http.StatusInternalServerError, PressErrorResponse{Error: err.Error()})
return
}
if lastPress != nil && lastPress.UserId == body.UserId {
if lastPress != nil && lastPress.UserId == user.UserId {
c.JSON(http.StatusBadRequest, PressErrorResponse{Error: data.ErrorPressedTwice})
return
}

// Get last press by user - if it's been less than 15s, return an error
lastPress, err = s.Store.GetLastPressByUser(body.UserId)
lastPress, err = s.Store.GetLastPressByUser(user.UserId)
if err != nil {
c.JSON(http.StatusInternalServerError, PressErrorResponse{Error: err.Error()})
return
Expand All @@ -101,7 +107,7 @@ func (s *Server) handlePostPress(c *gin.Context) {
}

// Register press
t, err := s.Store.PressButton(body.UserId)
t, err := s.Store.PressButton(user.UserId)
if err != nil {
c.JSON(http.StatusInternalServerError, PressErrorResponse{Error: err.Error()})
return
Expand All @@ -111,7 +117,7 @@ func (s *Server) handlePostPress(c *gin.Context) {
s.state.Presses.Add(1)
// Record press only if time is greater than the last press (cover race conditions)
if s.state.LastPress.Load() == nil || t > s.state.LastPress.Load().Time {
s.state.LastPress.Store(&data.Press{UserId: body.UserId, Time: t})
s.state.LastPress.Store(&data.Press{UserId: user.UserId, Time: t})
}

c.JSON(http.StatusOK, PressSuccessResponse{Time: t})
Expand All @@ -136,8 +142,10 @@ func (s *Server) handleGetData(c *gin.Context) {
var name = "no one"
lastPress := s.state.LastPress.Load()
if lastPress != nil {
// TODO resolve userId to name
name = lastPress.UserId
user, err := s.Users.GetUserById(lastPress.UserId)
if err == nil {
name = user.Name
}
}
c.JSON(http.StatusOK, newDataResponse(s.state.Presses.Load(), name, 1716015600000))
}
7 changes: 6 additions & 1 deletion data/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package data

import (
"encoding/json"
"errors"
"io"
"os"
)
Expand Down Expand Up @@ -44,5 +45,9 @@ func (s *LocalUserStorage) Init() error {
}

func (s *LocalUserStorage) GetUserById(id string) (*User, error) {
return s.users[id], nil
user, ok := s.users[id]
if !ok {
return nil, errors.New("user not found")
}
return user, nil
}
7 changes: 6 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ func main() {
log.Fatalf("Failed to initialize storage: %v", err)
}

router := api.NewAPIServer(":"+port, store)
users := data.NewLocalUserStorage()
if err := users.Init(); err != nil {
log.Fatalf("Failed to initialize user storage: %v", err)
}

router := api.NewAPIServer(":"+port, store, users)

log.Printf("Server is running on port %s", port)
log.Fatal(router.Run())
Expand Down

0 comments on commit 39ea215

Please sign in to comment.