// FolderHandler returns a list of resources pertaining to the room func FolderHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] room, err := repo.Load(hash) render.Check(err, w) var folder dropbox.Entry if room.Folder != "" { session, _ := cookieStore.Get(r, "dropbox") token := fmt.Sprintf("%v", session.Values["token"]) if token == "<nil>" { // FIXME: This could be more presentable http.Redirect(w, r, "/dropbox", 302) } url := fmt.Sprintf("https://api.dropbox.com/1/metadata/auto/%s", room.Folder) response, err := dropbox.Request("GET", url, token) render.Check(err, w) dropbox.DecodeResponse(response, &folder) } render.Render(w, r, "room_folder", map[string]interface{}{ "request": r, "room": room, "folder": folder, }) }
// SaveHandler saves a item func SaveHandler(w http.ResponseWriter, r *http.Request) { u, _ := auth.GetAuthenticatedUser(r) hash := r.FormValue("hash") name := r.FormValue("name") kind := Open folder := r.FormValue("folder") created := time.Now() if hash == "" { hash = crypto.UniqueHash(name) } room, err := repo.Load(hash) if err == nil { created = room.Created } room = &Room{Hash: hash, Name: name, Kind: kind, Folder: folder, Created: created} err = repo.Save(room) render.Check(err, w) // Add members to room members := r.Form["members"] members = append(members, u.Key) for _, user := range members { hash = crypto.Hash(room.Hash + user) rm := &RoomMember{Hash: hash, User: user, Room: room.Hash} err = roomMemberRepo.Save(rm) render.Check(err, w) } http.Redirect(w, r, "/r/"+room.Hash, http.StatusFound) }
// LeaveHandler allows people to leave rooms func LeaveHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] user, _ := auth.GetAuthenticatedUser(r) membership, err := roomMemberRepo.Load(hash, user.Key) render.Check(err, w) err = roomMemberRepo.Delete(membership.Hash) render.Check(err, w) http.Redirect(w, r, "/", 302) }
// JoinHandler allows people to join rooms func JoinHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] user, _ := auth.GetAuthenticatedUser(r) room, err := repo.Load(hash) render.Check(err, w) err = JoinRoom(room.Hash, user.Key) render.Check(err, w) http.Redirect(w, r, "/r/"+room.Hash, 302) }
// ListHandler returns all available rooms func ListHandler(w http.ResponseWriter, r *http.Request) { au, _ := auth.GetAuthenticatedUserKey(r) rooms, err := roomMemberRepo.ListRoomsForUser(au, 20) render.Check(err, w) joinable, err := roomMemberRepo.ListJoinableRoomsForUser(au, 20) render.Check(err, w) render.Render(w, r, "home", map[string]interface{}{ "request": r, "rooms": rooms, "joinable": joinable, }) }
func messageSaveHandler(w http.ResponseWriter, r *http.Request) { au, err := auth.GetAuthenticatedUser(r) if err != nil { http.Redirect(w, r, "/login", http.StatusFound) return } hash := r.FormValue("hash") room := r.FormValue("room") text := r.FormValue("text") if hash == "" { hash = crypto.UniqueHash(text) } m := &messages.Message{Hash: hash, Room: room, User: au.Key, Text: text} err = messageRepo.Save(m) render.Check(err, w) // Check for any resources in message go dropbox.HandleDropboxFilesPut("DMX/Test.gdoc", text, r) // Push members go push.PushMembers(room, m.Text) // Redirect to message (this is kind of a hack so we return the right JSON // to the clients connected over websockets). http.Redirect(w, r, "/m/"+hash, http.StatusFound) }
// BoardHandler returns board with its paths func BoardHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] board, err := repo.Load(hash) render.Check(err, w) paths, err := pathRepo.List(board.Hash) render.Check(err, w) render.Render(w, r, "board", map[string]interface{}{ "request": r, "board": board, "paths": paths, }) }
// MessageHandler returns a message func MessageHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] message, err := repo.Load(hash) render.Check(err, w) user, err := authRepo.Get(message.User) render.Check(err, w) render.Render(w, r, "message", map[string]interface{}{ "request": r, "message": message, "user": user, }) }
// HandleDropboxCallback handles Dropbox OAuth2 callback func HandleDropboxCallback(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{Name: "csrf", MaxAge: -1}) state := r.FormValue("state") cookie, _ := r.Cookie("csrf") if cookie == nil || cookie.Value != state { http.Error(w, "Possible CSRF attack.", http.StatusUnauthorized) return } resp, err := http.PostForm(fmt.Sprintf("https://%s:%[email protected]/1/oauth2/token", AppKey, AppSecret), url.Values{ "redirect_uri": {AppCallback}, "code": {r.FormValue("code")}, "grant_type": {"authorization_code"}, }) render.Check(err, w) var token Token DecodeResponse(resp, &token) // Saving session token session, _ := cookieStore.Get(r, "dropbox") session.Values["token"] = token.AccessToken session.Save(r, w) http.Redirect(w, r, "/", 302) }
// MemberHandler returns memebers for a room func MemberHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] room, err := repo.Load(hash) render.Check(err, w) members, err := roomMemberRepo.ListMembers(room.Hash) render.Check(err, w) render.Render(w, r, "room_members", map[string]interface{}{ "request": r, "room": room, "members": members, }) }
// ClearHandler removes all paths from a board func ClearHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] err := repo.Clear(hash) render.Check(err, w) http.Redirect(w, r, "/b/"+hash, 302) // FIXME: Should redirect to the board }
func userListHandler(w http.ResponseWriter, r *http.Request) { users, err := authRepo.List(100) render.Check(err, w) render.Render(w, r, "user_list", map[string]interface{}{ "request": r, "users": users, }) }
// UndoPathHandler removes a path from a board func UndoPathHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] err := pathRepo.Delete(hash) render.Check(err, w) http.Redirect(w, r, "/", 302) // FIXME: Should redirect to the board }
// FormHandler presents a form for creating a new room func FormHandler(w http.ResponseWriter, r *http.Request) { u, _ := auth.GetAuthenticatedUser(r) users, err := userRepo.List(100) render.Check(err, w) render.Render(w, r, "room_form", map[string]interface{}{ "request": r, "users": users, "user": u, }) }
// ListHandler returns all boards func ListHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] boards, err := repo.List(hash) render.Check(err, w) render.Render(w, r, "board_list", map[string]interface{}{ "request": r, "boards": boards, }) }
// SavePathHandler saves a path for a board func SavePathHandler(w http.ResponseWriter, r *http.Request) { u, _ := auth.GetAuthenticatedUser(r) hash := crypto.UniqueHash("") board := r.FormValue("board") data := r.FormValue("data") path := &Path{Hash: hash, Board: board, Data: data, User: u.Key} err := pathRepo.Save(path) render.Check(err, w) http.Redirect(w, r, "/b/"+board, http.StatusFound) }
// EditHandler handles editing of rooms func EditHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] u, _ := auth.GetAuthenticatedUser(r) users, err := userRepo.List(100) render.Check(err, w) room, err := repo.Load(hash) render.Check(err, w) members, err := roomMemberRepo.ListMembers(room.Hash) render.Check(err, w) render.Render(w, r, "room_form", map[string]interface{}{ "request": r, "room": room, "users": users, "members": members, "user": u, }) }
func oneOnOneHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] user1, _ := auth.GetAuthenticatedUser(r) user2, err := authRepo.Get(hash) render.Check(err, w) // Create a one-on-one room between the logged in user and the clicked on // user if the room doesn't already exist. room, err := roomRepo.LoadOneOnOne(user1.Key, user2.Key) if err != nil { roomHash := rooms.GenerateOneOnOneHash(user1.Key, user2.Key) room = &rooms.Room{Hash: roomHash, Name: roomHash, Kind: rooms.OneOnOne, Folder: "", Created: time.Now()} err = roomRepo.Save(room) render.Check(err, w) rooms.JoinRoom(roomHash, user1.Key) rooms.JoinRoom(roomHash, user2.Key) } render.Redirect(w, r, "/r/"+room.Hash) }
func roomHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hash := vars["hash"] userHash, _ := auth.GetAuthenticatedUserKey(r) room, err := roomRepo.Load(hash) render.Check(err, w) // If this is a private one-on-one room check whether the logged // in user is part of that room. If not, then they shouldn't be // able to view this room. if room.Kind == rooms.OneOnOne { _, err := roomMemberRepo.Load(room.Hash, userHash) if err != nil { render.Redirect(w, r, "/") return } } messages, err := messageRepo.List(hash, 20) render.Check(err, w) members, err := roomMemberRepo.ListMembers(room.Hash) render.Check(err, w) isMember, _ := roomMemberRepo.Load(room.Hash, userHash) render.Render(w, r, "room", map[string]interface{}{ "request": r, "room": room, "messages": messages, "members": members, "isMember": isMember, }) }
// SaveHandler saves a item func SaveHandler(w http.ResponseWriter, r *http.Request) { user, err := auth.GetAuthenticatedUser(r) if err != nil { http.Redirect(w, r, "/login", http.StatusFound) return } token := r.FormValue("token") platform := r.FormValue("platform") d := &Token{Token: token, Platform: platform, User: user.Key} err = repo.Insert(d) render.Check(err, w) http.Redirect(w, r, "/", http.StatusFound) }
// SaveHandler saves a board func SaveHandler(w http.ResponseWriter, r *http.Request) { hash := r.FormValue("hash") room := r.FormValue("room") name := r.FormValue("name") created := time.Now() if hash == "" { hash = crypto.UniqueHash(name) } board, err := repo.Load(hash) if err == nil { created = board.Created } board = &Board{Hash: hash, Room: room, Name: name, Created: created} err = repo.Save(board) render.Check(err, w) http.Redirect(w, r, "/b/"+board.Hash, http.StatusFound) }
// RegisterHandler registers a new user func RegisterHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { name := strings.TrimSpace(r.FormValue("name")) email := strings.TrimSpace(r.FormValue("email")) password := r.FormValue("password") // If email or password are blank then redirect to register page // TODO: provide a sensible error to people so they understand what // they did wrong. if email == "" || password == "" { render.Redirect(w, r, "/register") return } // Check to see if person already exists by attempting to log them in. passwordHash := crypto.PasswordHash(password) user, err := Authenticate(email, password, w, r) // If they do exist, redirect them home else create a new user and // log them into the site. if user != nil { render.Redirect(w, r, "/") return } key := crypto.UniqueHash(name) user = &User{Key: key, Name: name, Email: email, Password: passwordHash} err = repo.Insert(user) render.Check(err, w) // Auth user and redirect them user, _ = Authenticate(email, password, w, r) render.Redirect(w, r, "/") return } render.Render(w, r, "auth_register", nil) }