Added checks for occupying and leaving a seat based on permissions and user identity

main
Antonio De Lucreziis 3 years ago
parent 9058109615
commit b082257c1e

@ -32,10 +32,12 @@ type Authenticator interface {
// LoggedMiddleware accepts all logged users without checking for specific permissions
LoggedMiddleware() func(http.Handler) http.Handler
// UserFromSession returns the userID for this cookie session token
UserFromSession(r *http.Request) (string, error)
// RequestUser returns the userID for this cookie session token
RequestUser(r *http.Request) (string, error)
}
var _ Authenticator = &AuthService{}
type AuthService struct {
// CheckUserPassword
CheckUserPassword func(userID string, password string) error
@ -157,6 +159,7 @@ func (auth *AuthService) Middleware(config *AuthMiddlewareConfig) func(http.Hand
}
}
// LoggedMiddleware is a shortcut for "Middleware(*AuthMiddlewareConfig)" that checks if a user is logged, no extra permissions are checked
func (auth *AuthService) LoggedMiddleware() func(http.Handler) http.Handler {
return auth.Middleware(&AuthMiddlewareConfig{
RequireLogged: true,
@ -164,7 +167,8 @@ func (auth *AuthService) LoggedMiddleware() func(http.Handler) http.Handler {
})
}
func (auth *AuthService) UserFromSession(r *http.Request) (string, error) {
// RequestUser retrives the "userID" from the given request based on the cookie session token
func (auth *AuthService) RequestUser(r *http.Request) (string, error) {
cookie, err := r.Cookie(SessionCookieName)
if err != nil {
return "", err

@ -15,6 +15,16 @@ type User struct {
Permissions []string `json:"permissions"`
}
func (user User) HasPermission(neededPerm string) bool {
for _, perm := range user.Permissions {
if perm == neededPerm {
return true
}
}
return false
}
type Room struct {
ID string `json:"id"`
SeatIDs []string `json:"seatIds"`

@ -89,11 +89,7 @@ func NewServer() *Server {
roomIDs, _ := database.GetRooms()
for _, roomID := range roomIDs {
server.roomServerEventStreams[roomID] = serverevents.New(&serverevents.Config{
Connected: func(client chan string) {
server.ConnectedToRoom(roomID, client)
},
})
server.roomServerEventStreams[roomID] = serverevents.New(&serverevents.Config{})
}
server.setupRoutes()
@ -104,6 +100,7 @@ func NewServer() *Server {
func (server *Server) setupRoutes() {
api := server.ApiRoute
database := server.Database
auth := server.authService
// Authenticated Routes
@ -118,16 +115,16 @@ func (server *Server) setupRoutes() {
return
}
server.authService.Login(w, r, credentials.Username, credentials.Password)
auth.Login(w, r, credentials.Username, credentials.Password)
})
api.With(server.authService.LoggedMiddleware()).
api.With(auth.LoggedMiddleware()).
Post("/logout", func(w http.ResponseWriter, r *http.Request) {
server.authService.Logout(w)
auth.Logout(w)
})
api.Get("/user", func(w http.ResponseWriter, r *http.Request) {
userID, err := server.authService.UserFromSession(r)
userID, err := auth.RequestUser(r)
if err != nil {
httputil.WriteJSON(w, nil)
return
@ -177,14 +174,20 @@ func (server *Server) setupRoutes() {
server.roomServerEventStreams[roomID[0]].ServeHTTP(w, r)
})
api.With(server.authService.LoggedMiddleware()).
api.With(auth.LoggedMiddleware()).
Post("/seat/occupy", func(w http.ResponseWriter, r *http.Request) {
userID, err := server.authService.UserFromSession(r)
userID, err := auth.RequestUser(r)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
user, err := database.GetUser(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
seatID, ok := r.URL.Query()["id"]
if !ok {
http.Error(w, `missing seat id`, http.StatusBadRequest)
@ -193,22 +196,37 @@ func (server *Server) setupRoutes() {
seat, err := database.GetSeat(seatID[0])
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
repr.Println(userID, seatID)
if len(seat.OccupiedBy) == 0 {
if err := database.OccupySeat(seatID[0], user.ID); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
server.roomServerEventStreams[seat.RoomID].Broadcast("refresh")
httputil.WriteJSON(w, "ok")
} else {
http.Error(w, `seat already occupied`, http.StatusUnprocessableEntity)
}
})
api.With(auth.LoggedMiddleware()).
Post("/seat/leave", func(w http.ResponseWriter, r *http.Request) {
userID, err := auth.RequestUser(r)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
if err := database.OccupySeat(seatID[0], userID); err != nil {
user, err := database.GetUser(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
server.roomServerEventStreams[seat.RoomID].Broadcast("refresh")
httputil.WriteJSON(w, "ok")
})
api.With(server.authService.LoggedMiddleware()).
Post("/seat/leave", func(w http.ResponseWriter, r *http.Request) {
seatID, ok := r.URL.Query()["id"]
if !ok {
http.Error(w, `missing seat id`, http.StatusBadRequest)
@ -217,25 +235,28 @@ func (server *Server) setupRoutes() {
seat, err := database.GetSeat(seatID[0])
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
if err := database.FreeSeat(seatID[0]); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
server.roomServerEventStreams[seat.RoomID].Broadcast("refresh")
httputil.WriteJSON(w, "ok")
// Check permissions
if len(seat.OccupiedBy) > 0 {
if user.ID == seat.OccupiedBy[0] || user.HasPermission("admin") || user.HasPermission("moderator") {
if err := database.FreeSeat(seatID[0]); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
server.roomServerEventStreams[seat.RoomID].Broadcast("refresh")
httputil.WriteJSON(w, "ok")
} else {
http.Error(w, `seat can be freed only by its owner, a moderator or an admin`, http.StatusUnauthorized)
}
} else {
http.Error(w, `seat already empty`, http.StatusUnprocessableEntity)
}
})
}
func (server *Server) ConnectedToRoom(roomID string, client chan string) {
// go func() {
// for {
// client <- "hi from server!"
// time.Sleep(1 * time.Second)
// }
// }()
}
// func (server *Server) ConnectedToRoom(roomID string, client chan string)

Loading…
Cancel
Save