Added checks for occupying and leaving a seat based on permissions and user identity
This commit is contained in:
+7
-3
@@ -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"`
|
||||
|
||||
+57
-36
@@ -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)
|
||||
return
|
||||
}
|
||||
|
||||
repr.Println(userID, seatID)
|
||||
|
||||
if err := database.OccupySeat(seatID[0], userID); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
server.roomServerEventStreams[seat.RoomID].Broadcast("refresh")
|
||||
httputil.WriteJSON(w, "ok")
|
||||
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(server.authService.LoggedMiddleware()).
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user