Folders handlers
This commit is contained in:
parent
be36ed3593
commit
0bd63b53c5
|
@ -31,11 +31,21 @@ func (s Server) handleRegister(c Context) error {
|
||||||
log.Println("Can not generate hash from password: ", err)
|
log.Println("Can not generate hash from password: ", err)
|
||||||
return ApiError{Status: http.StatusInternalServerError, Err: "cannot register"}
|
return ApiError{Status: http.StatusInternalServerError, Err: "cannot register"}
|
||||||
}
|
}
|
||||||
|
userId := primitive.NewObjectID()
|
||||||
|
folderId := primitive.NewObjectID()
|
||||||
|
newFolder := storage.Folder{
|
||||||
|
Id: folderId,
|
||||||
|
UserID: userId,
|
||||||
|
Name: "root",
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
s.Db.CreateFolder(&newFolder)
|
||||||
newUser := storage.User{
|
newUser := storage.User{
|
||||||
Id: primitive.NewObjectID(),
|
Id: userId,
|
||||||
Username: form.Username,
|
Username: form.Username,
|
||||||
Password: password,
|
Password: password,
|
||||||
IsAdmin: true,
|
IsAdmin: true,
|
||||||
|
RootFolderId: folderId,
|
||||||
}
|
}
|
||||||
if _, err = s.Db.CreateUser(&newUser); err != nil {
|
if _, err = s.Db.CreateUser(&newUser); err != nil {
|
||||||
log.Println("Can not create user: ", err)
|
log.Println("Can not create user: ", err)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -25,6 +26,11 @@ func (s Server) handleNewBookmark(c Context) error {
|
||||||
}
|
}
|
||||||
ctx := c.R.Context()
|
ctx := c.R.Context()
|
||||||
user := ctx.Value(CtxValue("user")).(*storage.User)
|
user := ctx.Value(CtxValue("user")).(*storage.User)
|
||||||
|
log.Println(form)
|
||||||
|
if form.FolderID.IsZero() {
|
||||||
|
log.Println(user)
|
||||||
|
form.FolderID = user.RootFolderId
|
||||||
|
}
|
||||||
bookmark := storage.Bookmark{
|
bookmark := storage.Bookmark{
|
||||||
Id: primitive.NewObjectID(),
|
Id: primitive.NewObjectID(),
|
||||||
Name: form.Name,
|
Name: form.Name,
|
||||||
|
@ -41,6 +47,46 @@ func (s Server) handleNewBookmark(c Context) error {
|
||||||
return c.WriteJSON(201, &bookmark)
|
return c.WriteJSON(201, &bookmark)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Server) handleDeleteBookmark(c Context) error {
|
||||||
|
user := c.R.Context().Value(CtxValue("user")).(*storage.User)
|
||||||
|
idStr := c.GetVar("id")
|
||||||
|
id, err := primitive.ObjectIDFromHex(idStr)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "wrong id", Status: 400}
|
||||||
|
}
|
||||||
|
store := storage.NewStore[storage.Bookmark](&s.Db, "bookmarks")
|
||||||
|
bookmark, err := store.GetOne(context.TODO(), &bson.D{
|
||||||
|
{Key: "_id", Value: id},
|
||||||
|
{Key: "userid", Value: user.Id},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "not found", Status: 404}
|
||||||
|
}
|
||||||
|
err = store.DeleteByID(context.TODO(), bookmark.Id)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: err.Error(), Status: 500}
|
||||||
|
}
|
||||||
|
return c.WriteJSON(200, "removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Server) handleUpdateBookmark(c Context) error {
|
||||||
|
user := c.R.Context().Value(CtxValue("user")).(*storage.User)
|
||||||
|
var form storage.Bookmark
|
||||||
|
err := DecodeJSON(c.R.Body, &form)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "wrong body", Status: 400}
|
||||||
|
}
|
||||||
|
if form.UserID != user.Id {
|
||||||
|
return ApiError{Err: "wrong body", Status: 403}
|
||||||
|
}
|
||||||
|
store := storage.NewStore[storage.Bookmark](&s.Db, "bookmarks")
|
||||||
|
err = store.ReplaceByID(context.TODO(), form.Id, &form)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "couldn't update bookmark: " + err.Error(), Status: 500}
|
||||||
|
}
|
||||||
|
return c.WriteJSON(200, "updated")
|
||||||
|
}
|
||||||
|
|
||||||
func (s Server) handleGetBookmarks(c Context) error {
|
func (s Server) handleGetBookmarks(c Context) error {
|
||||||
ctx := c.R.Context()
|
ctx := c.R.Context()
|
||||||
user := ctx.Value(CtxValue("user")).(*storage.User) // Getting currently logged in user
|
user := ctx.Value(CtxValue("user")).(*storage.User) // Getting currently logged in user
|
||||||
|
@ -56,6 +102,21 @@ func (s Server) handleGetBookmarks(c Context) error {
|
||||||
return c.WriteJSON(200, bookmarks)
|
return c.WriteJSON(200, bookmarks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Server) handleGetLastBookmarks(c Context) error {
|
||||||
|
ctx := c.R.Context()
|
||||||
|
user := ctx.Value(CtxValue("user")).(*storage.User)
|
||||||
|
countVar := c.GetVar("count")
|
||||||
|
count, err := strconv.Atoi(countVar)
|
||||||
|
if err != nil {
|
||||||
|
count = 1
|
||||||
|
}
|
||||||
|
bookmarks, err := s.Db.GetLastBookmarks(count, &bson.D{{Key: "userid", Value: user.Id}})
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "can't get bookmarks: " + err.Error(), Status: 400}
|
||||||
|
}
|
||||||
|
return c.WriteJSON(200, bookmarks)
|
||||||
|
}
|
||||||
|
|
||||||
func (s Server) handleGetRandomBookmarks(c Context) error {
|
func (s Server) handleGetRandomBookmarks(c Context) error {
|
||||||
ctx := c.R.Context()
|
ctx := c.R.Context()
|
||||||
user := ctx.Value(CtxValue("user")).(*storage.User)
|
user := ctx.Value(CtxValue("user")).(*storage.User)
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.nefrace.ru/nefrace/nashboard/storage"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
|
type newFolderForm struct {
|
||||||
|
Name string
|
||||||
|
ParentID primitive.ObjectID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Server) handleNewFolder(c Context) error {
|
||||||
|
var form newFolderForm
|
||||||
|
err := DecodeJSON(c.R.Body, &form)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "can't decode json to folder: " + err.Error(), Status: 400}
|
||||||
|
}
|
||||||
|
ctx := c.R.Context()
|
||||||
|
user := ctx.Value(CtxValue("user")).(*storage.User)
|
||||||
|
if form.ParentID.IsZero() {
|
||||||
|
rootFolder, _ := s.Db.GetFolder(&bson.D{{Key: "name", Value: "root"}})
|
||||||
|
form.ParentID = rootFolder.Id
|
||||||
|
}
|
||||||
|
folder := storage.Folder{
|
||||||
|
Id: primitive.NewObjectID(),
|
||||||
|
Name: form.Name,
|
||||||
|
UserID: user.Id,
|
||||||
|
ParentID: form.ParentID,
|
||||||
|
// Tags: form.Tags,
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
_, err = s.Db.CreateFolder(&folder)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "can't safe folder: " + err.Error(), Status: 500}
|
||||||
|
}
|
||||||
|
return c.WriteJSON(201, &folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
type folderResult struct {
|
||||||
|
Folder *storage.Folder
|
||||||
|
ChildFolders []*storage.Folder
|
||||||
|
ChildBookmarks []*storage.Bookmark
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Server) handleGetFolder(c Context) error {
|
||||||
|
user := c.R.Context().Value(CtxValue("user")).(*storage.User) // Getting currently logged in user
|
||||||
|
userFilter := bson.E{Key: "userid", Value: user.Id}
|
||||||
|
idStr := c.GetVar("id")
|
||||||
|
query := c.R.URL.Query()
|
||||||
|
filter := storage.QueryFilter(&query)
|
||||||
|
filter = append(filter, userFilter)
|
||||||
|
if idStr != "" {
|
||||||
|
id, err := primitive.ObjectIDFromHex(idStr)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "wrong id", Status: 400}
|
||||||
|
}
|
||||||
|
filter = bson.D{{Key: "_id", Value: id}, userFilter}
|
||||||
|
}
|
||||||
|
folder, err := s.Db.GetFolder(&filter)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "not found", Status: 404}
|
||||||
|
}
|
||||||
|
folders, _ := s.Db.GetChildrenFolders(folder.Id)
|
||||||
|
bookmarks, _ := s.Db.GetChildrenBookmarks(folder.Id)
|
||||||
|
return c.WriteJSON(200, &folderResult{
|
||||||
|
Folder: folder,
|
||||||
|
ChildFolders: folders,
|
||||||
|
ChildBookmarks: bookmarks,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Server) handleUpdateFolder(c Context) error {
|
||||||
|
user := c.R.Context().Value(CtxValue("user")).(*storage.User)
|
||||||
|
var form storage.Folder
|
||||||
|
err := DecodeJSON(c.R.Body, &form)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "wrong body", Status: 400}
|
||||||
|
}
|
||||||
|
if form.UserID != user.Id {
|
||||||
|
return ApiError{Err: "wrong body", Status: 403}
|
||||||
|
}
|
||||||
|
store := storage.NewStore[storage.Folder](&s.Db, "folders")
|
||||||
|
err = store.ReplaceByID(context.TODO(), form.Id, &form)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "couldn't update folder: " + err.Error(), Status: 500}
|
||||||
|
}
|
||||||
|
return c.WriteJSON(200, "updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Server) handleDeleteFolder(c Context) error {
|
||||||
|
user := c.R.Context().Value(CtxValue("user")).(*storage.User)
|
||||||
|
idStr := c.GetVar("id")
|
||||||
|
id, err := primitive.ObjectIDFromHex(idStr)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "wrong id", Status: 400}
|
||||||
|
}
|
||||||
|
store := storage.NewStore[storage.Folder](&s.Db, "folders")
|
||||||
|
folder, err := store.GetOne(context.TODO(), &bson.D{
|
||||||
|
{Key: "_id", Value: id},
|
||||||
|
{Key: "userid", Value: user.Id},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: "not found", Status: 404}
|
||||||
|
}
|
||||||
|
err = store.DeleteByID(context.TODO(), folder.Id)
|
||||||
|
if err != nil {
|
||||||
|
return ApiError{Err: err.Error(), Status: 500}
|
||||||
|
}
|
||||||
|
return c.WriteJSON(200, "removed")
|
||||||
|
}
|
|
@ -38,12 +38,26 @@ func (s Server) InitHandlers() {
|
||||||
// userRouter.Use(s.AuthorizedOnly)
|
// userRouter.Use(s.AuthorizedOnly)
|
||||||
userRouter.Path("/me").HandlerFunc(MakeHTTPHandler(s.handleGetMe))
|
userRouter.Path("/me").HandlerFunc(MakeHTTPHandler(s.handleGetMe))
|
||||||
userRouter.Path("/all").HandlerFunc(MakeHTTPHandler(s.handleAllUsers))
|
userRouter.Path("/all").HandlerFunc(MakeHTTPHandler(s.handleAllUsers))
|
||||||
|
|
||||||
bookmarkRouter := apiRouter.PathPrefix("/bookmark").Subrouter()
|
bookmarkRouter := apiRouter.PathPrefix("/bookmark").Subrouter()
|
||||||
bookmarkRouter.Use(s.AuthorizedOnly)
|
bookmarkRouter.Use(s.AuthorizedOnly)
|
||||||
bookmarkRouter.Path("").Methods("GET").HandlerFunc(MakeHTTPHandler(s.handleGetBookmarks))
|
bookmarkRouter.Path("").Methods("GET").HandlerFunc(MakeHTTPHandler(s.handleGetBookmarks))
|
||||||
bookmarkRouter.Path("").Methods("POST").HandlerFunc(MakeHTTPHandler(s.handleNewBookmark))
|
bookmarkRouter.Path("").Methods("POST").HandlerFunc(MakeHTTPHandler(s.handleNewBookmark))
|
||||||
|
bookmarkRouter.Path("").Methods("PUT").HandlerFunc(MakeHTTPHandler(s.handleUpdateBookmark))
|
||||||
|
bookmarkRouter.Path("{id}").Methods("DELETE").HandlerFunc(MakeHTTPHandler(s.handleDeleteBookmark))
|
||||||
|
bookmarkRouter.Path("/last").HandlerFunc(MakeHTTPHandler(s.handleGetLastBookmarks))
|
||||||
|
bookmarkRouter.Path("/last/{count}").HandlerFunc(MakeHTTPHandler(s.handleGetLastBookmarks))
|
||||||
bookmarkRouter.Path("/random").HandlerFunc(MakeHTTPHandler(s.handleGetRandomBookmarks))
|
bookmarkRouter.Path("/random").HandlerFunc(MakeHTTPHandler(s.handleGetRandomBookmarks))
|
||||||
bookmarkRouter.Path("/random/{count}").HandlerFunc(MakeHTTPHandler(s.handleGetRandomBookmarks))
|
bookmarkRouter.Path("/random/{count}").HandlerFunc(MakeHTTPHandler(s.handleGetRandomBookmarks))
|
||||||
|
|
||||||
|
folderRouter := apiRouter.PathPrefix("/f").Subrouter()
|
||||||
|
folderRouter.Use(s.AuthorizedOnly)
|
||||||
|
folderRouter.Path("").Methods("GET").HandlerFunc(MakeHTTPHandler(s.handleGetFolder))
|
||||||
|
folderRouter.Path("").Methods("POST").HandlerFunc(MakeHTTPHandler(s.handleNewFolder))
|
||||||
|
folderRouter.Path("").Methods("PUT").HandlerFunc(MakeHTTPHandler(s.handleUpdateFolder))
|
||||||
|
folderRouter.Path("{id}").Methods("GET").HandlerFunc(MakeHTTPHandler(s.handleGetFolder))
|
||||||
|
folderRouter.Path("{id}").Methods("DELETE").HandlerFunc(MakeHTTPHandler(s.handleDeleteFolder))
|
||||||
|
folderRouter.Path("/{name}").HandlerFunc(MakeHTTPHandler(s.handleGetFolder))
|
||||||
|
|
||||||
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
|
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MongodbStorage struct {
|
type MongodbStorage struct {
|
||||||
|
@ -116,6 +117,21 @@ func (m MongodbStorage) GetRandomBookmarks(count int, filter *bson.D) ([]*Bookma
|
||||||
return bookmarks, err
|
return bookmarks, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) GetLastBookmarks(count int, filter *bson.D) ([]*Bookmark, error) {
|
||||||
|
passedFilter := getFilter(filter)
|
||||||
|
ctx := context.TODO()
|
||||||
|
store := NewStore[Bookmark](&m, "bookmarks")
|
||||||
|
bookmarks := []*Bookmark{}
|
||||||
|
opts := options.Find().SetSort(bson.D{{Key: "created", Value: -1}}).SetLimit(int64(count))
|
||||||
|
cur, err := store.Coll.Find(ctx, passedFilter, opts)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Cant find last bookmakrs: ", err)
|
||||||
|
return bookmarks, err
|
||||||
|
}
|
||||||
|
cur.All(ctx, &bookmarks)
|
||||||
|
return bookmarks, err
|
||||||
|
}
|
||||||
|
|
||||||
func (m MongodbStorage) GetUserBookmarks(user *User, filter *bson.D) ([]*Bookmark, error) {
|
func (m MongodbStorage) GetUserBookmarks(user *User, filter *bson.D) ([]*Bookmark, error) {
|
||||||
passedFilter := getFilter(filter)
|
passedFilter := getFilter(filter)
|
||||||
f := bson.D{{Key: "userid", Value: user.Id}}
|
f := bson.D{{Key: "userid", Value: user.Id}}
|
||||||
|
@ -125,6 +141,36 @@ func (m MongodbStorage) GetUserBookmarks(user *User, filter *bson.D) ([]*Bookmar
|
||||||
return store.GetMany(ctx, &f)
|
return store.GetMany(ctx, &f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) CreateFolder(folder *Folder) (primitive.ObjectID, error) {
|
||||||
|
store := NewStore[Folder](&m, "folders")
|
||||||
|
return store.InsertOne(context.TODO(), folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) GetFolderByID(id primitive.ObjectID) (*Folder, error) {
|
||||||
|
store := NewStore[Folder](&m, "folders")
|
||||||
|
return store.GetById(context.TODO(), id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) GetFolder(filter *bson.D) (*Folder, error) {
|
||||||
|
store := NewStore[Folder](&m, "folders")
|
||||||
|
return store.GetOne(context.TODO(), filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) GetFolders(filter *bson.D) ([]*Folder, error) {
|
||||||
|
store := NewStore[Folder](&m, "folders")
|
||||||
|
return store.GetMany(context.TODO(), filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) GetChildrenFolders(id primitive.ObjectID) ([]*Folder, error) {
|
||||||
|
store := NewStore[Folder](&m, "folders")
|
||||||
|
return store.GetMany(context.TODO(), &bson.D{{Key: "parentid", Value: id}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MongodbStorage) GetChildrenBookmarks(id primitive.ObjectID) ([]*Bookmark, error) {
|
||||||
|
store := NewStore[Bookmark](&m, "bookmarks")
|
||||||
|
return store.GetMany(context.TODO(), &bson.D{{Key: "folderid", Value: id}})
|
||||||
|
}
|
||||||
|
|
||||||
func (m MongodbStorage) Collection(col string) *mongo.Collection {
|
func (m MongodbStorage) Collection(col string) *mongo.Collection {
|
||||||
return m.Db.Database("nash").Collection(col)
|
return m.Db.Database("nash").Collection(col)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Id primitive.ObjectID `bson:"_id" json:"id,omitempty"`
|
Id primitive.ObjectID `bson:"_id" json:"id,omitempty"`
|
||||||
Username string
|
Username string
|
||||||
Password []byte `json:"-"`
|
Password []byte `json:"-"`
|
||||||
IsAdmin bool
|
IsAdmin bool
|
||||||
LastLogin time.Time
|
LastLogin time.Time
|
||||||
|
RootFolderId primitive.ObjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
|
@ -36,7 +37,9 @@ type Folder struct {
|
||||||
Id primitive.ObjectID `bson:"_id" json:"id,omitempty"`
|
Id primitive.ObjectID `bson:"_id" json:"id,omitempty"`
|
||||||
Name string
|
Name string
|
||||||
ParentID primitive.ObjectID
|
ParentID primitive.ObjectID
|
||||||
|
UserID primitive.ObjectID
|
||||||
Icon []byte
|
Icon []byte
|
||||||
|
Created time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bookmark struct {
|
type Bookmark struct {
|
||||||
|
@ -46,8 +49,8 @@ type Bookmark struct {
|
||||||
UserID primitive.ObjectID
|
UserID primitive.ObjectID
|
||||||
FolderID primitive.ObjectID
|
FolderID primitive.ObjectID
|
||||||
Tags []string
|
Tags []string
|
||||||
// Icon []byte
|
Icon []byte
|
||||||
Created time.Time
|
Created time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type Note struct {
|
type Note struct {
|
||||||
|
|
Loading…
Reference in New Issue