diff --git a/server/db/database.go b/server/db/database.go index 21ade98..bee8d3a 100644 --- a/server/db/database.go +++ b/server/db/database.go @@ -106,16 +106,6 @@ type Store interface { // TODO: Create an SQLite implementation -// memDB is the first Store implementation used for testing. -type memDB struct { - // FIXME: Giusto per la cronaca fare le modifiche in questo modo alle mappe non è per niente thread safe, servirebbe come minimo usare un mutex per quando si scrive su una di queste variabili - // mutex *sync.Mutex - - users map[string]*User - rooms map[string]*Room - seats map[string]*Seat -} - // NewInMemoryStore creates an instance of memDB hidden behind the Store interface. func NewInMemoryStore() Store { db := &memDB{ @@ -155,149 +145,3 @@ func NewInMemoryStore() Store { return db } - -// -// memDB Implementation -// - -func (db *memDB) CreateUser(user *User) error { - if _, present := db.users[user.ID]; present { - return ErrAlreadyExists - } - db.users[user.ID] = user - return nil -} - -func (db *memDB) CreateRoom(room *Room) error { - if _, present := db.rooms[room.ID]; present { - return ErrAlreadyExists - } - db.rooms[room.ID] = room - return nil -} - -func (db *memDB) CreateSeat(seat *Seat) error { - if _, present := db.seats[seat.ID]; present { - return ErrAlreadyExists - } - db.seats[seat.ID] = seat - return nil -} - -func (db *memDB) DeleteUser(user *User) error { - if _, present := db.users[user.ID]; !present { - return ErrDoesntExist - } - - delete(db.users, user.ID) - return nil -} - -func (db *memDB) DeleteRoom(room *Room) error { - if _, present := db.rooms[room.ID]; !present { - return ErrDoesntExist - } - - delete(db.rooms, room.ID) - return nil -} - -func (db *memDB) DeleteSeat(seat *Seat) error { - if _, present := db.seats[seat.ID]; !present { - return ErrDoesntExist - } - - delete(db.seats, seat.ID) - return nil -} - -func (db *memDB) GetUser(userID string) (*User, error) { - user, present := db.users[userID] - if !present { - return nil, fmt.Errorf(`no such user "%s"`, userID) - } - - return user, nil -} - -func (db *memDB) GetRoom(roomID string) (*Room, error) { - room, present := db.rooms[roomID] - if !present { - return nil, fmt.Errorf(`no such room "%s"`, roomID) - } - - return room, nil -} - -func (db *memDB) GetSeat(seatID string) (*Seat, error) { - seat, present := db.seats[seatID] - if !present { - return nil, fmt.Errorf(`no such seat "%s"`, seatID) - } - - return seat, nil -} - -func (db *memDB) GetRooms() ([]string, error) { - roomIDs := []string{} - - for roomID := range db.rooms { - roomIDs = append(roomIDs, roomID) - } - - return roomIDs, nil -} - -func (db *memDB) GetRoomOccupiedSeats(roomID string) ([]string, error) { - room, err := db.GetRoom(roomID) - if err != nil { - return nil, err - } - - seats := []string{} - for _, seatID := range room.SeatIDs { - seat := db.seats[seatID] - if len(seat.OccupiedBy) == 1 { - seats = append(seats, seatID) - } - } - - return seats, nil -} - -func (db *memDB) GetRoomFreeSeats(roomID string) ([]string, error) { - room, err := db.GetRoom(roomID) - if err != nil { - return nil, err - } - - seats := []string{} - for _, seatID := range room.SeatIDs { - seat := db.seats[seatID] - if len(seat.OccupiedBy) == 0 { - seats = append(seats, seatID) - } - } - - return seats, nil -} - -func (db *memDB) GetUserSeat(userID string) ([]string, error) { - for _, seat := range db.seats { - if len(seat.OccupiedBy) > 0 && seat.OccupiedBy[0] == userID { - return []string{userID}, nil - } - } - - return []string{}, nil -} - -func (db *memDB) OccupySeat(seatID, userID string) error { - db.seats[seatID].OccupiedBy = []string{userID} - return nil -} - -func (db *memDB) FreeSeat(seatID string) error { - db.seats[seatID].OccupiedBy = []string{} - return nil -} diff --git a/server/db/inmemory.go b/server/db/inmemory.go new file mode 100644 index 0000000..8fe8f88 --- /dev/null +++ b/server/db/inmemory.go @@ -0,0 +1,155 @@ +package db + +import "fmt" + +// memDB is the first Store implementation used for testing. +type memDB struct { + // FIXME: Giusto per la cronaca fare le modifiche in questo modo alle mappe non è per niente thread safe, servirebbe come minimo usare un mutex per quando si scrive su una di queste variabili + // mutex *sync.Mutex + + users map[string]*User + rooms map[string]*Room + seats map[string]*Seat +} + +func (db *memDB) CreateUser(user *User) error { + if _, present := db.users[user.ID]; present { + return ErrAlreadyExists + } + db.users[user.ID] = user + return nil +} + +func (db *memDB) CreateRoom(room *Room) error { + if _, present := db.rooms[room.ID]; present { + return ErrAlreadyExists + } + db.rooms[room.ID] = room + return nil +} + +func (db *memDB) CreateSeat(seat *Seat) error { + if _, present := db.seats[seat.ID]; present { + return ErrAlreadyExists + } + db.seats[seat.ID] = seat + return nil +} + +func (db *memDB) DeleteUser(user *User) error { + if _, present := db.users[user.ID]; !present { + return ErrDoesntExist + } + + delete(db.users, user.ID) + return nil +} + +func (db *memDB) DeleteRoom(room *Room) error { + if _, present := db.rooms[room.ID]; !present { + return ErrDoesntExist + } + + delete(db.rooms, room.ID) + return nil +} + +func (db *memDB) DeleteSeat(seat *Seat) error { + if _, present := db.seats[seat.ID]; !present { + return ErrDoesntExist + } + + delete(db.seats, seat.ID) + return nil +} + +func (db *memDB) GetUser(userID string) (*User, error) { + user, present := db.users[userID] + if !present { + return nil, fmt.Errorf(`no such user "%s"`, userID) + } + + return user, nil +} + +func (db *memDB) GetRoom(roomID string) (*Room, error) { + room, present := db.rooms[roomID] + if !present { + return nil, fmt.Errorf(`no such room "%s"`, roomID) + } + + return room, nil +} + +func (db *memDB) GetSeat(seatID string) (*Seat, error) { + seat, present := db.seats[seatID] + if !present { + return nil, fmt.Errorf(`no such seat "%s"`, seatID) + } + + return seat, nil +} + +func (db *memDB) GetRooms() ([]string, error) { + roomIDs := []string{} + + for roomID := range db.rooms { + roomIDs = append(roomIDs, roomID) + } + + return roomIDs, nil +} + +func (db *memDB) GetRoomOccupiedSeats(roomID string) ([]string, error) { + room, err := db.GetRoom(roomID) + if err != nil { + return nil, err + } + + seats := []string{} + for _, seatID := range room.SeatIDs { + seat := db.seats[seatID] + if len(seat.OccupiedBy) == 1 { + seats = append(seats, seatID) + } + } + + return seats, nil +} + +func (db *memDB) GetRoomFreeSeats(roomID string) ([]string, error) { + room, err := db.GetRoom(roomID) + if err != nil { + return nil, err + } + + seats := []string{} + for _, seatID := range room.SeatIDs { + seat := db.seats[seatID] + if len(seat.OccupiedBy) == 0 { + seats = append(seats, seatID) + } + } + + return seats, nil +} + +func (db *memDB) GetUserSeat(userID string) ([]string, error) { + for _, seat := range db.seats { + if len(seat.OccupiedBy) > 0 && seat.OccupiedBy[0] == userID { + return []string{userID}, nil + } + } + + return []string{}, nil +} + +func (db *memDB) OccupySeat(seatID, userID string) error { + db.seats[seatID].OccupiedBy = []string{userID} + return nil +} + +func (db *memDB) FreeSeat(seatID string) error { + db.seats[seatID].OccupiedBy = []string{} + return nil +} diff --git a/server/httputil/response.go b/server/httputil/response.go index 96dc404..ee21763 100644 --- a/server/httputil/response.go +++ b/server/httputil/response.go @@ -5,8 +5,7 @@ import ( "net/http" ) -type H map[string]interface{} - +// WriteJSON returns the data as json to the client. func WriteJSON(w http.ResponseWriter, data interface{}) { w.Header().Set("Content-Type", "application/json") err := json.NewEncoder(w).Encode(data) @@ -15,6 +14,7 @@ func WriteJSON(w http.ResponseWriter, data interface{}) { } } +// ReadJSON decodes the request body inside the given pointer. func ReadJSON(r *http.Request, data interface{}) error { return json.NewDecoder(r.Body).Decode(data) } diff --git a/server/server.go b/server/server.go index fb67f64..ed97fd4 100644 --- a/server/server.go +++ b/server/server.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log" "net/http" "git.phc.dm.unipi.it/aziis98/posti-dm/server/auth" @@ -9,7 +10,6 @@ import ( "git.phc.dm.unipi.it/aziis98/posti-dm/server/httputil" "git.phc.dm.unipi.it/aziis98/posti-dm/server/httputil/serverevents" "git.phc.dm.unipi.it/aziis98/posti-dm/server/util" - "github.com/alecthomas/repr" "github.com/go-chi/chi/v5" ) @@ -35,10 +35,14 @@ func NewServer() *Server { } // FIXME: al momento quando la password è giusta creiamo tutti gli account necessari - database.CreateUser(&db.User{ + err := database.CreateUser(&db.User{ ID: userID, Permissions: []string{}, }) + if err != nil { + log.Printf(`got "%v" while trying to log as @%s`, err, userID) + return nil + } return nil }, @@ -56,9 +60,8 @@ func NewServer() *Server { return "", err } - token := util.RandomHash(10) + token := util.RandomHash(20) sessions[token] = user - repr.Println("Sessions: ", sessions) return token, nil }, diff --git a/server/util/hash.go b/server/util/hash.go index 6b7fd58..daa8a3f 100644 --- a/server/util/hash.go +++ b/server/util/hash.go @@ -5,6 +5,7 @@ import ( "encoding/base64" ) +// RandomHash generates a random cryptograph base64 string of the given length. func RandomHash(len int) string { buff := make([]byte, len) rand.Read(buff)