| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | package http | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	"sort" | 
					
						
							|  |  |  | 	"strconv" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | 	fm "github.com/hacdias/filemanager" | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | type modifyRequest struct { | 
					
						
							|  |  |  | 	What  string `json:"what"`  // Answer to: what data type?
 | 
					
						
							|  |  |  | 	Which string `json:"which"` // Answer to: which field?
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type modifyUserRequest struct { | 
					
						
							|  |  |  | 	*modifyRequest | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | 	Data *fm.User `json:"data"` | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | // usersHandler is the entry point of the users API. It's just a router
 | 
					
						
							|  |  |  | // to send the request to its
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | func usersHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// If the user isn't admin and isn't making a PUT
 | 
					
						
							|  |  |  | 	// request, then return forbidden.
 | 
					
						
							|  |  |  | 	if !c.User.Admin && r.Method != http.MethodPut { | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 		return http.StatusForbidden, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	switch r.Method { | 
					
						
							|  |  |  | 	case http.MethodGet: | 
					
						
							|  |  |  | 		return usersGetHandler(c, w, r) | 
					
						
							|  |  |  | 	case http.MethodPost: | 
					
						
							|  |  |  | 		return usersPostHandler(c, w, r) | 
					
						
							|  |  |  | 	case http.MethodDelete: | 
					
						
							|  |  |  | 		return usersDeleteHandler(c, w, r) | 
					
						
							|  |  |  | 	case http.MethodPut: | 
					
						
							|  |  |  | 		return usersPutHandler(c, w, r) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return http.StatusNotImplemented, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | // getUserID returns the id from the user which is present
 | 
					
						
							|  |  |  | // in the request url. If the url is invalid and doesn't
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | // contain a valid ID, it returns an fm.Error.
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | func getUserID(r *http.Request) (int, error) { | 
					
						
							|  |  |  | 	// Obtains the ID in string from the URL and converts
 | 
					
						
							|  |  |  | 	// it into an integer.
 | 
					
						
							|  |  |  | 	sid := strings.TrimPrefix(r.URL.Path, "/") | 
					
						
							|  |  |  | 	sid = strings.TrimSuffix(sid, "/") | 
					
						
							|  |  |  | 	id, err := strconv.Atoi(sid) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusBadRequest, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return id, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // getUser returns the user which is present in the request
 | 
					
						
							|  |  |  | // body. If the body is empty or the JSON is invalid, it
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | // returns an fm.Error.
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | func getUser(c *fm.Context, r *http.Request) (*fm.User, string, error) { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Checks if the request body is empty.
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	if r.Body == nil { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return nil, "", fm.ErrEmptyRequest | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Parses the request body and checks if it's well formed.
 | 
					
						
							|  |  |  | 	mod := &modifyUserRequest{} | 
					
						
							|  |  |  | 	err := json.NewDecoder(r.Body).Decode(mod) | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		return nil, "", err | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Checks if the request type is right.
 | 
					
						
							|  |  |  | 	if mod.What != "user" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return nil, "", fm.ErrWrongDataType | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	mod.Data.FileSystem = c.NewFS(mod.Data.Scope) | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	return mod.Data, mod.Which, nil | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | func usersGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	// Request for the default user data.
 | 
					
						
							|  |  |  | 	if r.URL.Path == "/base" { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		return renderJSON(w, c.DefaultUser) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	// Request for the listing of users.
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if r.URL.Path == "/" { | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 		users, err := c.Store.Users.Gets(c.NewFS) | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		for _, u := range users { | 
					
						
							|  |  |  | 			// Removes the user password so it won't
 | 
					
						
							|  |  |  | 			// be sent to the front-end.
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 			u.Password = "" | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sort.Slice(users, func(i, j int) bool { | 
					
						
							|  |  |  | 			return users[i].ID < users[j].ID | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return renderJSON(w, users) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	id, err := getUserID(r) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 		return http.StatusInternalServerError, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	u, err := c.Store.Users.Get(id, c.NewFS) | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	if err == fm.ErrExist { | 
					
						
							|  |  |  | 		return http.StatusNotFound, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	u.Password = "" | 
					
						
							|  |  |  | 	return renderJSON(w, u) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | func usersPostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if r.URL.Path != "/" { | 
					
						
							|  |  |  | 		return http.StatusMethodNotAllowed, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	u, _, err := getUser(c, r) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 		return http.StatusBadRequest, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Checks if username isn't empty.
 | 
					
						
							|  |  |  | 	if u.Username == "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return http.StatusBadRequest, fm.ErrEmptyUsername | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	// Checks if scope isn't empty.
 | 
					
						
							|  |  |  | 	if u.Scope == "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return http.StatusBadRequest, fm.ErrEmptyScope | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Checks if password isn't empty.
 | 
					
						
							|  |  |  | 	if u.Password == "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return http.StatusBadRequest, fm.ErrEmptyPassword | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	// Initialize rules if they're not initialized.
 | 
					
						
							|  |  |  | 	if u.Rules == nil { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		u.Rules = []*fm.Rule{} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-31 18:23:31 +00:00
										 |  |  | 	// If the view mode is empty, initialize with the default one.
 | 
					
						
							|  |  |  | 	if u.ViewMode == "" { | 
					
						
							|  |  |  | 		u.ViewMode = c.DefaultUser.ViewMode | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	// Initialize commands if not initialized.
 | 
					
						
							|  |  |  | 	if u.Commands == nil { | 
					
						
							|  |  |  | 		u.Commands = []string{} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// It's a new user so the ID will be auto created.
 | 
					
						
							|  |  |  | 	if u.ID != 0 { | 
					
						
							|  |  |  | 		u.ID = 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | 	// Checks if the scope exists.
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	if code, err := checkFS(u.Scope); err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | 		return code, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	// Hashes the password.
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	pw, err := fm.HashPassword(u.Password) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u.Password = pw | 
					
						
							| 
									
										
										
										
											2017-10-09 07:26:05 +00:00
										 |  |  | 	u.ViewMode = fm.MosaicViewMode | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Saves the user to the database.
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	err = c.Store.Users.Save(u) | 
					
						
							|  |  |  | 	if err == fm.ErrExist { | 
					
						
							|  |  |  | 		return http.StatusConflict, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the Location header and return.
 | 
					
						
							| 
									
										
										
										
											2017-09-07 15:37:11 +00:00
										 |  |  | 	w.Header().Set("Location", "/settings/users/"+strconv.Itoa(u.ID)) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	w.WriteHeader(http.StatusCreated) | 
					
						
							|  |  |  | 	return 0, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | func checkFS(path string) (int, error) { | 
					
						
							|  |  |  | 	info, err := os.Stat(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		if !os.IsNotExist(err) { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		err = os.MkdirAll(path, 0666) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 11:18:51 +00:00
										 |  |  | 		return 0, nil | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !info.IsDir() { | 
					
						
							|  |  |  | 		return http.StatusBadRequest, errors.New("Scope is not a dir") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | func usersDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if r.URL.Path == "/" { | 
					
						
							|  |  |  | 		return http.StatusMethodNotAllowed, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	id, err := getUserID(r) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 		return http.StatusInternalServerError, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	// Deletes the user from the database.
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	err = c.Store.Users.Delete(id) | 
					
						
							|  |  |  | 	if err == fm.ErrNotExist { | 
					
						
							|  |  |  | 		return http.StatusNotFound, fm.ErrNotExist | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return http.StatusOK, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:00:32 +00:00
										 |  |  | func usersPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// New users should be created on /api/users.
 | 
					
						
							|  |  |  | 	if r.URL.Path == "/" { | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 		return http.StatusMethodNotAllowed, nil | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Gets the user ID from the URL and checks if it's valid.
 | 
					
						
							|  |  |  | 	id, err := getUserID(r) | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		return http.StatusInternalServerError, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Checks if the user has permission to access this page.
 | 
					
						
							|  |  |  | 	if !c.User.Admin && id != c.User.ID { | 
					
						
							|  |  |  | 		return http.StatusForbidden, nil | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Gets the user from the request body.
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	u, which, err := getUser(c, r) | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		return http.StatusBadRequest, err | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-11 08:46:17 +00:00
										 |  |  | 	// If we're updating the default user. Only for NoAuth
 | 
					
						
							|  |  |  | 	// implementations. Used to change the viewMode.
 | 
					
						
							|  |  |  | 	if id == 0 && c.NoAuth { | 
					
						
							|  |  |  | 		c.DefaultUser.ViewMode = u.ViewMode | 
					
						
							|  |  |  | 		return http.StatusOK, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Updates the CSS and locale.
 | 
					
						
							|  |  |  | 	if which == "partial" { | 
					
						
							|  |  |  | 		c.User.CSS = u.CSS | 
					
						
							|  |  |  | 		c.User.Locale = u.Locale | 
					
						
							| 
									
										
										
										
											2017-09-07 09:29:19 +00:00
										 |  |  | 		c.User.ViewMode = u.ViewMode | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 09:29:19 +00:00
										 |  |  | 		err = c.Store.Users.Update(c.User, "CSS", "Locale", "ViewMode") | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		return http.StatusOK, nil | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Updates the Password.
 | 
					
						
							|  |  |  | 	if which == "password" { | 
					
						
							|  |  |  | 		if u.Password == "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 			return http.StatusBadRequest, fm.ErrEmptyPassword | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 13:44:53 +00:00
										 |  |  | 		if id == c.User.ID && c.User.LockPassword { | 
					
						
							|  |  |  | 			return http.StatusForbidden, nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		c.User.Password, err = fm.HashPassword(u.Password) | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		err = c.Store.Users.Update(c.User, "Password") | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 		return http.StatusOK, nil | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// If can only be all.
 | 
					
						
							|  |  |  | 	if which != "all" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return http.StatusBadRequest, fm.ErrInvalidUpdateField | 
					
						
							| 
									
										
										
										
											2017-07-26 16:50:39 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Checks if username isn't empty.
 | 
					
						
							|  |  |  | 	if u.Username == "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return http.StatusBadRequest, fm.ErrEmptyUsername | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Checks if filesystem isn't empty.
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	if u.Scope == "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		return http.StatusBadRequest, fm.ErrEmptyScope | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | 	// Checks if the scope exists.
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	if code, err := checkFS(u.Scope); err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-10 10:21:06 +00:00
										 |  |  | 		return code, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	// Initialize rules if they're not initialized.
 | 
					
						
							|  |  |  | 	if u.Rules == nil { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		u.Rules = []*fm.Rule{} | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Initialize commands if not initialized.
 | 
					
						
							|  |  |  | 	if u.Commands == nil { | 
					
						
							|  |  |  | 		u.Commands = []string{} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Gets the current saved user from the in-memory map.
 | 
					
						
							| 
									
										
										
										
											2017-08-20 08:21:36 +00:00
										 |  |  | 	suser, err := c.Store.Users.Get(id, c.NewFS) | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	if err == fm.ErrNotExist { | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 		return http.StatusNotFound, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	u.ID = id | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	// Changes the password if the request wants it.
 | 
					
						
							|  |  |  | 	if u.Password != "" { | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 		pw, err := fm.HashPassword(u.Password) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		u.Password = pw | 
					
						
							| 
									
										
										
										
											2017-08-01 19:49:56 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		u.Password = suser.Password | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Updates the whole User struct because we always are supposed
 | 
					
						
							|  |  |  | 	// to send a new entire object.
 | 
					
						
							| 
									
										
										
										
											2017-08-19 11:35:44 +00:00
										 |  |  | 	err = c.Store.Users.Update(u) | 
					
						
							| 
									
										
										
										
											2017-07-08 16:51:47 +00:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return http.StatusInternalServerError, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return http.StatusOK, nil | 
					
						
							|  |  |  | } |