initial commit on github
This commit is contained in:
Executable
+300
@@ -0,0 +1,300 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func RegisterUsersRoutes(r *mux.Router) {
|
||||
r.HandleFunc("/users", resolveUsers).Methods("GET", "OPTIONS", "POST")
|
||||
r.HandleFunc("/users/me", resolveCurrentUser).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/users/me/avatar", uploadAvatar).Methods("OPTIONS", "POST")
|
||||
r.HandleFunc("/users/me/settings", resolveSettings).Methods("GET", "OPTIONS", "POST")
|
||||
r.HandleFunc("/users/{userId:[0-9]+}", resolveUser).Methods("GET", "OPTIONS", "PUT")
|
||||
r.HandleFunc("/users/{userId:[0-9]+}/novels", resolveUserNovels).Methods("GET", "OPTIONS", "POST")
|
||||
r.HandleFunc("/users/{userId:[0-9]+}/novels/{novelId:[0-9]+}", resolveUserNovel).Methods("GET", "OPTIONS", "PUT", "DELETE")
|
||||
r.HandleFunc("/users/{userId:[0-9]+}/novels/comments", resolveUserNovelsComments).Methods("GET", "OPTIONS", "POST")
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
UseGravatar bool `json:"use_gravatar" db:"use_gravatar"`
|
||||
Avatar string `json:"avatar"`
|
||||
Theme string `json:"theme"`
|
||||
}
|
||||
|
||||
func resolveSettings(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := GetCurrentUserID(r)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method == "GET" {
|
||||
settings, err := FetchUserSettings(id)
|
||||
Response(w, err, settings)
|
||||
} else if r.Method == "POST" {
|
||||
settings, err := FetchUserSettings(id)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ReadBody(r)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, settings)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := UpdateUserSettings(id, settings)
|
||||
Response(w, err, user)
|
||||
}
|
||||
}
|
||||
|
||||
func resolveUsers(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
users, err := FetchUsers()
|
||||
Response(w, err, users)
|
||||
} else {
|
||||
RawError(w, "Work in progress...")
|
||||
}
|
||||
}
|
||||
|
||||
func resolveCurrentUser(w http.ResponseWriter, r *http.Request) {
|
||||
user, err := FetchCurrentUser(r)
|
||||
if err == ErrNotAuthorized {
|
||||
NoToken.Ferror(w)
|
||||
return
|
||||
}
|
||||
if err == http.ErrNoCookie {
|
||||
NoToken.Ferror(w)
|
||||
return
|
||||
}
|
||||
Response(w, err, user)
|
||||
}
|
||||
|
||||
func resolveUser(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, _ := strconv.Atoi(vars["userId"])
|
||||
|
||||
if r.Method == http.MethodGet {
|
||||
user, err := FetchUser(id)
|
||||
Response(w, err, user)
|
||||
return
|
||||
}
|
||||
|
||||
currentUser, err := FetchCurrentUser(r)
|
||||
if err != nil && err != ErrNotAuthorized {
|
||||
Error(w, err)
|
||||
return
|
||||
} else if err == ErrNotAuthorized || currentUser == nil {
|
||||
currentUser = &User{ID: -1}
|
||||
}
|
||||
|
||||
if r.Method == http.MethodPut {
|
||||
if currentUser.ID != int64(id) && !hasPermission(currentUser, "users") {
|
||||
NoAccess.Ferror(w)
|
||||
return
|
||||
}
|
||||
_, err := FetchUser(id)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ReadBody(r)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
var u *User
|
||||
err = json.Unmarshal(body, u)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
user, err := UpdateUser(u)
|
||||
Response(w, err, user)
|
||||
}
|
||||
}
|
||||
|
||||
func uploadAvatar(w http.ResponseWriter, r *http.Request) {
|
||||
user, err := FetchCurrentUser(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = r.ParseMultipartForm(user.Group.MaxAvaWeight)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
file, handler, err := r.FormFile("avatar")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(handler.Header["Content-Type"][0], "image") {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
RawError(w, "Wrong document type!")
|
||||
return
|
||||
}
|
||||
|
||||
fileBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
img, _, err := image.DecodeConfig(bytes.NewReader(fileBytes))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
width, height := img.Width, img.Width
|
||||
if width > user.Group.MaxAvatarSize && height > user.Group.MaxAvatarSize {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
RawError(w, "Image too big!")
|
||||
return
|
||||
}
|
||||
|
||||
ext := strings.Split(handler.Header["Content-Type"][0], "/")[1]
|
||||
path := filepath.Join(config.CDNPath, "users", "avatars", fmt.Sprintf("%v.%v", user.ID, ext))
|
||||
|
||||
err = ioutil.WriteFile(path, fileBytes, 0644)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
avatarPath := fmt.Sprintf("%v/users/avatars/%v.%v", config.CDNUrl, user.ID, ext)
|
||||
Response(w, nil, avatarPath)
|
||||
}
|
||||
|
||||
func resolveUserNovels(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
userId, _ := strconv.Atoi(vars["userId"])
|
||||
|
||||
if r.Method == http.MethodGet {
|
||||
novels, err := FetchUserNovels(userId)
|
||||
Response(w, err, novels)
|
||||
} else if r.Method == http.MethodPost {
|
||||
body, err := ReadBody(r)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
var novel = &UserNovels{}
|
||||
err = json.Unmarshal(body, novel)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
novel.UserID = int64(userId)
|
||||
|
||||
novel, err = CreateUserNovel(novel)
|
||||
if err == nil {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Header().Add("Location", fmt.Sprintf("https://%v%v/%v", r.Host, r.URL, novel.NovelID))
|
||||
}
|
||||
Response(w, err, novel)
|
||||
}
|
||||
}
|
||||
|
||||
func resolveUserNovel(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
userId, _ := strconv.Atoi(vars["userId"])
|
||||
novelId, _ := strconv.Atoi(vars["novelId"])
|
||||
|
||||
if r.Method == http.MethodGet {
|
||||
novel, err := FetchUserNovel(userId, novelId)
|
||||
Response(w, err, novel)
|
||||
} else if r.Method == http.MethodPut {
|
||||
_, err := FetchNovel(novelId)
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound.Ferror(w)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = FetchUser(userId)
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound.Ferror(w)
|
||||
return
|
||||
}
|
||||
|
||||
novel, _ := FetchUserNovel(userId, novelId)
|
||||
body, err := ReadBody(r)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if novel == nil {
|
||||
NotFound.Ferror(w)
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &novel)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
updatedNovel, err := UpdateUserNovel(novel)
|
||||
lpServer.PushEvent(updatedNovel, uint64(userId), "update-user-novel")
|
||||
Response(w, err, updatedNovel)
|
||||
} else if r.Method == http.MethodDelete {
|
||||
_, err := FetchUserNovel(userId, novelId)
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound.Ferror(w)
|
||||
return
|
||||
}
|
||||
|
||||
err = DeleteUserNovel(userId, novelId)
|
||||
if err != nil {
|
||||
Error(w, err)
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
func resolveUserNovelsComments(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, _ := strconv.Atoi(vars["userId"])
|
||||
|
||||
comments, err := FetchUserNovelsComments(id)
|
||||
Response(w, err, comments)
|
||||
}
|
||||
Reference in New Issue
Block a user