DB Updates :)

Former-commit-id: e9795cfca39aab57f4a4b604c65633958ff22e46 [formerly 7dd93e46eb6915a387dc64500a3fe7f6f955643b] [formerly ffa277f1605e46bb8c914464b1223fe029d579d8 [formerly a04ff87bf9]]
Former-commit-id: ffa472fd3b1534f64a1c343864564bbc0290714b [formerly 7074f824d7d7dd3cd74b884c9f3e96834f662394]
Former-commit-id: 4b1e0324de6065fd4daec25d463d3756588b92d8
This commit is contained in:
Henrique Dias 2017-08-19 12:35:44 +01:00
parent 4b602be5e3
commit 764289e52f
15 changed files with 337 additions and 297 deletions

View file

@ -1,14 +1,11 @@
package http
import (
"crypto/rand"
"encoding/json"
"net/http"
"strings"
"time"
"golang.org/x/crypto/bcrypt"
jwt "github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
fm "github.com/hacdias/filemanager"
@ -33,13 +30,13 @@ func authHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, er
}
// Checks if the user exists.
u, ok := c.Users[cred.Username]
if !ok {
u, err := c.Store.Users.Get(cred.ID)
if err != nil {
return http.StatusForbidden, nil
}
// Checks if the password is correct.
if !checkPasswordHash(cred.Password, u.Password) {
if !fm.CheckPasswordHash(cred.Password, u.Password) {
return http.StatusForbidden, nil
}
@ -86,7 +83,7 @@ func printToken(c *fm.Context, w http.ResponseWriter) (int, error) {
// Creates the token and signs it.
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signed, err := token.SignedString(c.key)
signed, err := token.SignedString(c.Key)
if err != nil {
return http.StatusInternalServerError, err
@ -127,7 +124,7 @@ func validateAuth(c *fm.Context, r *http.Request) (bool, *fm.User) {
}
keyFunc := func(token *jwt.Token) (interface{}, error) {
return c.key, nil
return c.Key, nil
}
var claims claims
token, err := request.ParseFromRequestWithClaims(r,
@ -140,38 +137,11 @@ func validateAuth(c *fm.Context, r *http.Request) (bool, *fm.User) {
return false, nil
}
u, ok := c.Users[claims.User.Username]
if !ok {
u, err := c.Store.Users.Get(claims.User.ID)
if err != nil {
return false, nil
}
c.User = u
return true, u
}
// hashPassword generates an hash from a password using bcrypt.
func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
// checkPasswordHash compares a password with an hash to check if they match.
func checkPasswordHash(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
// generateRandomBytes returns securely generated random bytes.
// It will return an error if the system's secure random
// number generator fails to function correctly, in which
// case the caller should not continue.
func generateRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
// Note that err == nil only if we read len(b) bytes.
if err != nil {
return nil, err
}
return b, nil
}

View file

@ -45,7 +45,7 @@ func TestRenewHandler(t *testing.T) {
// First, we have to make an auth request to get the user authenticated,
r, err := http.NewRequest("POST", "/api/auth/get", strings.NewReader(defaultCredentials))
if err != nil {
t.Fatal(err)
t.Fatal(fm.Err)
}
w := httptest.NewRecorder()
@ -60,7 +60,7 @@ func TestRenewHandler(t *testing.T) {
// Test renew authorization via Authorization Header.
r, err = http.NewRequest("GET", "/api/auth/renew", nil)
if err != nil {
t.Fatal(err)
t.Fatal(fm.Err)
}
r.Header.Set("Authorization", "Bearer "+token)
@ -74,7 +74,7 @@ func TestRenewHandler(t *testing.T) {
// Test renew authorization via cookie field.
r, err = http.NewRequest("GET", "/api/auth/renew", nil)
if err != nil {
t.Fatal(err)
t.Fatal(fm.Err)
}
r.AddCookie(&http.Cookie{

View file

@ -2,7 +2,6 @@ package http
import (
"encoding/json"
"errors"
"html/template"
"net/http"
"os"
@ -13,21 +12,10 @@ import (
fm "github.com/hacdias/filemanager"
)
var (
errUserExist = errors.New("user already exists")
errUserNotExist = errors.New("user does not exist")
errEmptyRequest = errors.New("request body is empty")
errEmptyPassword = errors.New("password is empty")
errEmptyUsername = errors.New("username is empty")
errEmptyScope = errors.New("scope is empty")
errWrongDataType = errors.New("wrong data type")
errInvalidUpdateField = errors.New("invalid field to update")
)
// ServeHTTP is the main entry point of this HTML application.
func ServeHTTP(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
// Checks if the URL contains the baseURL and strips it. Otherwise, it just
// returns a 404 error because we're not supposed to be here!
// returns a 404 fm.Error because we're not supposed to be here!
p := strings.TrimPrefix(r.URL.Path, c.BaseURL)
if len(p) >= len(r.URL.Path) && c.BaseURL != "" {
@ -41,7 +29,7 @@ func ServeHTTP(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
if r.URL.Path == "/sw.js" {
return renderFile(
c, w,
c.assets.MustString("sw.js"),
c.Assets.MustString("sw.js"),
"application/javascript",
)
}
@ -83,7 +71,7 @@ func ServeHTTP(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
return renderFile(
c, w,
c.assets.MustString("index.html"),
c.Assets.MustString("index.html"),
"text/html",
)
}
@ -91,13 +79,13 @@ func ServeHTTP(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
// staticHandler handles the static assets path.
func staticHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
if r.URL.Path != "/static/manifest.json" {
http.FileServer(c.assets.HTTPBox()).ServeHTTP(w, r)
http.FileServer(c.Assets.HTTPBox()).ServeHTTP(w, r)
return 0, nil
}
return renderFile(
c, w,
c.assets.MustString("static/manifest.json"),
c.Assets.MustString("static/manifest.json"),
"application/json",
)
}
@ -141,7 +129,7 @@ func apiHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, err
var err error
c.File, err = fm.GetInfo(r.URL, c.FileManager, c.User)
if err != nil {
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
}
@ -177,7 +165,7 @@ func checksumHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
query := r.URL.Query().Get("algo")
val, err := c.File.Checksum(query)
if err == errInvalidOption {
if err == fm.ErrInvalidOption {
return http.StatusBadRequest, err
} else if err != nil {
return http.StatusInternalServerError, err
@ -211,7 +199,7 @@ func renderFile(c *fm.Context, w http.ResponseWriter, file string, contentType s
err := tpl.Execute(w, map[string]interface{}{
"BaseURL": c.RootURL(),
"StaticGen": c.staticgen,
"StaticGen": c.StaticGen.Name(),
})
if err != nil {
return http.StatusInternalServerError, err
@ -221,12 +209,11 @@ func renderFile(c *fm.Context, w http.ResponseWriter, file string, contentType s
}
func sharePage(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
var s shareLink
err := c.db.One("Hash", r.URL.Path, &s)
s, err := c.Store.Share.Get(r.URL.Path)
if err == storm.ErrNotFound {
return renderFile(
c, w,
c.assets.MustString("static/share/404.html"),
c.Assets.MustString("static/share/404.html"),
"text/html",
)
}
@ -236,10 +223,10 @@ func sharePage(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
}
if s.Expires && s.ExpireDate.Before(time.Now()) {
c.db.DeleteStruct(&s)
c.Store.Share.Delete(s.Hash)
return renderFile(
c, w,
c.assets.MustString("static/share/404.html"),
c.Assets.MustString("static/share/404.html"),
"text/html",
)
}
@ -248,10 +235,10 @@ func sharePage(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
info, err := os.Stat(s.Path)
if err != nil {
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
c.File = &file{
c.File = &fm.File{
Path: s.Path,
Name: info.Name(),
ModTime: info.ModTime(),
@ -263,7 +250,7 @@ func sharePage(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, erro
dl := r.URL.Query().Get("dl")
if dl == "" || dl == "0" {
tpl := template.Must(template.New("file").Parse(c.assets.MustString("static/share/index.html")))
tpl := template.Must(template.New("file").Parse(c.Assets.MustString("static/share/index.html")))
w.Header().Set("Content-Type", "text/html; charset=utf-8")
err := tpl.Execute(w, map[string]interface{}{
@ -303,8 +290,8 @@ func matchURL(first, second string) bool {
return strings.HasPrefix(first, second)
}
// errorToHTTP converts errors to HTTP Status Code.
func errorToHTTP(err error, gone bool) int {
// ErrorToHTTP converts errors to HTTP Status Code.
func ErrorToHTTP(err error, gone bool) int {
switch {
case err == nil:
return http.StatusOK

View file

@ -64,9 +64,9 @@ func resourceHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
func resourceGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
// Gets the information of the directory/file.
f, err := getInfo(r.URL, c.FileManager, c.User)
f, err := fm.GetInfo(r.URL, c.FileManager, c.User)
if err != nil {
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
// If it's a dir and the path doesn't end with a trailing slash,
@ -83,7 +83,7 @@ func resourceGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
// Tries to get the file type.
if err = f.GetFileType(true); err != nil {
return errorToHTTP(err, true), err
return ErrorToHTTP(err, true), err
}
// Serve a preview if the file can't be edited or the
@ -97,7 +97,7 @@ func resourceGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
f.Kind = "editor"
// Tries to get the editor data.
if err = f.getEditor(); err != nil {
if err = f.GetEditor(); err != nil {
return http.StatusInternalServerError, err
}
@ -109,11 +109,11 @@ func listingHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int,
f.Kind = "listing"
// Tries to get the listing data.
if err := f.getListing(c, r); err != nil {
return errorToHTTP(err, true), err
if err := f.GetListing(c.User, r); err != nil {
return ErrorToHTTP(err, true), err
}
listing := f.listing
listing := f.Listing
// Defines the cookie scope.
cookieScope := c.RootURL()
@ -144,7 +144,7 @@ func resourceDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request
// Remove the file or folder.
err := c.User.FileSystem.RemoveAll(r.URL.Path)
if err != nil {
return errorToHTTP(err, true), err
return ErrorToHTTP(err, true), err
}
return http.StatusOK, nil
@ -160,7 +160,7 @@ func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Reques
}
// Discard any invalid upload before returning to avoid connection
// reset error.
// reset fm.Error.
defer func() {
io.Copy(ioutil.Discard, r.Body)
}()
@ -175,13 +175,13 @@ func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Reques
// Otherwise we try to create the directory.
err := c.User.FileSystem.Mkdir(r.URL.Path, 0776)
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
// If using POST method, we are trying to create a new file so it is not
// desirable to override an already existent file. Thus, we check
// desirable to ovfm.Erride an already existent file. Thus, we check
// if the file already exists. If so, we just return a 409 Conflict.
if r.Method == http.MethodPost && r.Header.Get("Action") != "override" {
if r.Method == http.MethodPost && r.Header.Get("Action") != "ovfm.Erride" {
if _, err := c.User.FileSystem.Stat(r.URL.Path); err == nil {
return http.StatusConflict, errors.New("There is already a file on that path")
}
@ -190,20 +190,20 @@ func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Reques
// Create/Open the file.
f, err := c.User.FileSystem.OpenFile(r.URL.Path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0776)
if err != nil {
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
defer f.Close()
// Copies the new content for the file.
_, err = io.Copy(f, r.Body)
if err != nil {
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
// Gets the info about the file.
fi, err := f.Stat()
if err != nil {
return errorToHTTP(err, false), err
return ErrorToHTTP(err, false), err
}
// Check if this instance has a Static Generator and handles publishing
@ -242,7 +242,7 @@ func resourcePublishSchedule(c *fm.Context, w http.ResponseWriter, r *http.Reque
return http.StatusInternalServerError, err
}
c.cron.AddFunc(t.Format("05 04 15 02 01 *"), func() {
c.Cron.AddFunc(t.Format("05 04 15 02 01 *"), func() {
_, err := resourcePublish(c, w, r)
if err != nil {
log.Print(err)
@ -283,7 +283,7 @@ func resourcePatchHandler(c *fm.Context, w http.ResponseWriter, r *http.Request)
action := r.Header.Get("Action")
dst, err := url.QueryUnescape(dst)
if err != nil {
return errorToHTTP(err, true), err
return ErrorToHTTP(err, true), err
}
src := r.URL.Path
@ -298,7 +298,7 @@ func resourcePatchHandler(c *fm.Context, w http.ResponseWriter, r *http.Request)
err = c.User.FileSystem.Rename(src, dst)
}
return errorToHTTP(err, true), err
return ErrorToHTTP(err, true), err
}
// displayMode obtains the display mode from the Cookie.

View file

@ -27,7 +27,7 @@ type option struct {
func parsePutSettingsRequest(r *http.Request) (*modifySettingsRequest, error) {
// Checks if the request body is empty.
if r.Body == nil {
return nil, errEmptyRequest
return nil, fm.ErrEmptyRequest
}
// Parses the request body and checks if it's well formed.
@ -39,7 +39,7 @@ func parsePutSettingsRequest(r *http.Request) (*modifySettingsRequest, error) {
// Checks if the request type is right.
if mod.What != "settings" {
return nil, errWrongDataType
return nil, fm.ErrWrongDataType
}
return mod, nil
@ -103,9 +103,10 @@ func settingsPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
if err != nil {
return http.StatusBadRequest, err
}
// Update the commands.
if mod.Which == "commands" {
if err := c.db.Set("config", "commands", mod.Data.Commands); err != nil {
if err := c.Store.Config.Save("commands", mod.Data.Commands); err != nil {
return http.StatusInternalServerError, err
}
@ -120,7 +121,7 @@ func settingsPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
return http.StatusInternalServerError, err
}
err = c.db.Set("staticgen", c.staticgen, c.StaticGen)
err = c.Store.Config.Save("staticgen_"+c.StaticGen.Name(), c.StaticGen)
if err != nil {
return http.StatusInternalServerError, err
}

View file

@ -13,13 +13,6 @@ import (
fm "github.com/hacdias/filemanager"
)
type shareLink struct {
Hash string `json:"hash" storm:"id,index"`
Path string `json:"path" storm:"index"`
Expires bool `json:"expires"`
ExpireDate time.Time `json:"expireDate"`
}
func shareHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
r.URL.Path = sanitizeURL(r.URL.Path)
@ -36,12 +29,8 @@ func shareHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, e
}
func shareGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
var (
s []*shareLink
path = filepath.Join(string(c.User.FileSystem), r.URL.Path)
)
err := c.db.Find("Path", path, &s)
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
s, err := c.Store.Share.GetByPath(path)
if err == storm.ErrNotFound {
return http.StatusNotFound, nil
}
@ -52,7 +41,7 @@ func shareGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
for i, link := range s {
if link.Expires && link.ExpireDate.Before(time.Now()) {
c.db.DeleteStruct(&shareLink{Hash: link.Hash})
c.Store.Share.Delete(link.Hash)
s = append(s[:i], s[i+1:]...)
}
}
@ -63,7 +52,7 @@ func shareGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
var s shareLink
var s fm.ShareLink
expire := r.URL.Query().Get("expires")
unit := r.URL.Query().Get("unit")
@ -75,14 +64,14 @@ func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
}
}
bytes, err := generateRandomBytes(32)
bytes, err := fm.GenerateRandomBytes(32)
if err != nil {
return http.StatusInternalServerError, err
}
str := hex.EncodeToString(bytes)
s = shareLink{
s = fm.ShareLink{
Path: path,
Hash: str,
Expires: expire != "",
@ -109,8 +98,7 @@ func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
s.ExpireDate = time.Now().Add(add)
}
err = c.db.Save(&s)
if err != nil {
if err := c.Store.Share.Save(&s); err != nil {
return http.StatusInternalServerError, err
}
@ -118,9 +106,7 @@ func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
}
func shareDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
var s shareLink
err := c.db.One("Hash", strings.TrimPrefix(r.URL.Path, "/"), &s)
s, err := c.Store.Share.Get(strings.TrimPrefix(r.URL.Path, "/"))
if err == storm.ErrNotFound {
return http.StatusNotFound, nil
}
@ -129,7 +115,7 @@ func shareDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
return http.StatusInternalServerError, err
}
err = c.db.DeleteStruct(&s)
err = c.Store.Share.Delete(s.Hash)
if err != nil {
return http.StatusInternalServerError, err
}

View file

@ -9,7 +9,6 @@ import (
"strconv"
"strings"
"github.com/asdine/storm"
fm "github.com/hacdias/filemanager"
)
@ -48,7 +47,7 @@ func usersHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, e
// getUserID returns the id from the user which is present
// in the request url. If the url is invalid and doesn't
// contain a valid ID, it returns an error.
// contain a valid ID, it returns an fm.Error.
func getUserID(r *http.Request) (int, error) {
// Obtains the ID in string from the URL and converts
// it into an integer.
@ -64,11 +63,11 @@ func getUserID(r *http.Request) (int, error) {
// getUser returns the user which is present in the request
// body. If the body is empty or the JSON is invalid, it
// returns an error.
// returns an fm.Error.
func getUser(r *http.Request) (*fm.User, string, error) {
// Checks if the request body is empty.
if r.Body == nil {
return nil, "", errEmptyRequest
return nil, "", fm.ErrEmptyRequest
}
// Parses the request body and checks if it's well formed.
@ -80,7 +79,7 @@ func getUser(r *http.Request) (*fm.User, string, error) {
// Checks if the request type is right.
if mod.What != "user" {
return nil, "", errWrongDataType
return nil, "", fm.ErrWrongDataType
}
return mod.Data, mod.Which, nil
@ -94,15 +93,15 @@ func usersGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
// Request for the listing of users.
if r.URL.Path == "/" {
users := []User{}
users, err := c.Store.Users.Gets()
if err != nil {
return http.StatusInternalServerError, err
}
for _, user := range c.Users {
// Copies the user info and removes its
// password so it won't be sent to the
// front-end.
u := *user
for _, u := range users {
// Removes the user password so it won't
// be sent to the front-end.
u.Password = ""
users = append(users, u)
}
sort.Slice(users, func(i, j int) bool {
@ -117,19 +116,17 @@ func usersGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
return http.StatusInternalServerError, err
}
// Searches for the user and prints the one who matches.
for _, user := range c.Users {
if user.ID != id {
continue
}
u := *user
u.Password = ""
return renderJSON(w, u)
u, err := c.Store.Users.Get(id)
if err == fm.ErrExist {
return http.StatusNotFound, err
}
// If there aren't any matches, return not found.
return http.StatusNotFound, errUserNotExist
if err != nil {
return http.StatusInternalServerError, err
}
u.Password = ""
return renderJSON(w, u)
}
func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
@ -144,17 +141,17 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
// Checks if username isn't empty.
if u.Username == "" {
return http.StatusBadRequest, errEmptyUsername
return http.StatusBadRequest, fm.ErrEmptyUsername
}
// Checks if filesystem isn't empty.
if u.FileSystem == "" {
return http.StatusBadRequest, errEmptyScope
return http.StatusBadRequest, fm.ErrEmptyScope
}
// Checks if password isn't empty.
if u.Password == "" {
return http.StatusBadRequest, errEmptyPassword
return http.StatusBadRequest, fm.ErrEmptyPassword
}
// The username, password and scope cannot be empty.
@ -164,7 +161,7 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
// Initialize rules if they're not initialized.
if u.Rules == nil {
u.Rules = []*Rule{}
u.Rules = []*fm.Rule{}
}
// Initialize commands if not initialized.
@ -183,7 +180,7 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
}
// Hashes the password.
pw, err := hashPassword(u.Password)
pw, err := fm.HashPassword(u.Password)
if err != nil {
return http.StatusInternalServerError, err
}
@ -191,18 +188,15 @@ func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (in
u.Password = pw
// Saves the user to the database.
err = c.db.Save(u)
if err == storm.ErrAlreadyExists {
return http.StatusConflict, errUserExist
err = c.Store.Users.Save(u)
if err == fm.ErrExist {
return http.StatusConflict, err
}
if err != nil {
return http.StatusInternalServerError, err
}
// Saves the user to the memory.
c.Users[u.Username] = u
// Set the Location header and return.
w.Header().Set("Location", "/users/"+strconv.Itoa(u.ID))
w.WriteHeader(http.StatusCreated)
@ -243,23 +237,15 @@ func usersDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (
}
// Deletes the user from the database.
err = c.db.DeleteStruct(&User{ID: id})
if err == storm.ErrNotFound {
return http.StatusNotFound, errUserNotExist
err = c.Store.Users.Delete(id)
if err == fm.ErrNotExist {
return http.StatusNotFound, fm.ErrNotExist
}
if err != nil {
return http.StatusInternalServerError, err
}
// Delete the user from the in-memory users map.
for _, user := range c.Users {
if user.ID == id {
delete(c.Users, user.Username)
break
}
}
return http.StatusOK, nil
}
@ -290,12 +276,8 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
if which == "partial" {
c.User.CSS = u.CSS
c.User.Locale = u.Locale
err = c.db.UpdateField(&User{ID: c.User.ID}, "CSS", u.CSS)
if err != nil {
return http.StatusInternalServerError, err
}
err = c.db.UpdateField(&User{ID: c.User.ID}, "Locale", u.Locale)
err = c.Store.Users.Update(c.User, "CSS", "Locale")
if err != nil {
return http.StatusInternalServerError, err
}
@ -306,16 +288,15 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
// Updates the Password.
if which == "password" {
if u.Password == "" {
return http.StatusBadRequest, errEmptyPassword
return http.StatusBadRequest, fm.ErrEmptyPassword
}
pw, err := hashPassword(u.Password)
c.User.Password, err = fm.HashPassword(u.Password)
if err != nil {
return http.StatusInternalServerError, err
}
c.User.Password = pw
err = c.db.UpdateField(&User{ID: c.User.ID}, "Password", pw)
err = c.Store.Users.Update(c.User, "Password")
if err != nil {
return http.StatusInternalServerError, err
}
@ -325,17 +306,17 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
// If can only be all.
if which != "all" {
return http.StatusBadRequest, errInvalidUpdateField
return http.StatusBadRequest, fm.ErrInvalidUpdateField
}
// Checks if username isn't empty.
if u.Username == "" {
return http.StatusBadRequest, errEmptyUsername
return http.StatusBadRequest, fm.ErrEmptyUsername
}
// Checks if filesystem isn't empty.
if u.FileSystem == "" {
return http.StatusBadRequest, errEmptyScope
return http.StatusBadRequest, fm.ErrEmptyScope
}
// Checks if the scope exists.
@ -345,7 +326,7 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
// Initialize rules if they're not initialized.
if u.Rules == nil {
u.Rules = []*Rule{}
u.Rules = []*fm.Rule{}
}
// Initialize commands if not initialized.
@ -354,22 +335,20 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
}
// Gets the current saved user from the in-memory map.
var suser *User
for _, user := range c.Users {
if user.ID == id {
suser = user
break
}
}
if suser == nil {
suser, err := c.Store.Users.Get(id)
if err == fm.ErrNotExist {
return http.StatusNotFound, nil
}
if err != nil {
return http.StatusInternalServerError, err
}
u.ID = id
// Changes the password if the request wants it.
if u.Password != "" {
pw, err := hashPassword(u.Password)
pw, err := fm.HashPassword(u.Password)
if err != nil {
return http.StatusInternalServerError, err
}
@ -381,17 +360,10 @@ func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
// Updates the whole User struct because we always are supposed
// to send a new entire object.
err = c.db.Save(u)
err = c.Store.Users.Update(u)
if err != nil {
return http.StatusInternalServerError, err
}
// If the user changed the username, delete the old user
// from the in-memory user map.
if suser.Username != u.Username {
delete(c.Users, suser.Username)
}
c.Users[u.Username] = u
return http.StatusOK, nil
}

View file

@ -28,7 +28,7 @@ var (
// command handles the requests for VCS related commands: git, svn and mercurial
func command(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
// Upgrades the connection to a websocket and checks for errors.
// Upgrades the connection to a websocket and checks for fm.Errors.
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return 0, err
@ -92,7 +92,7 @@ func command(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error)
cmd.Stderr = buff
cmd.Stdout = buff
// Starts the command and checks for errors.
// Starts the command and checks for fm.Errors.
err = cmd.Start()
if err != nil {
return http.StatusInternalServerError, err
@ -241,7 +241,7 @@ func parseSearch(value string) *searchOptions {
// search searches for a file or directory.
func search(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
// Upgrades the connection to a websocket and checks for errors.
// Upgrades the connection to a websocket and checks for fm.Errors.
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return 0, err