func PullFile(wsConn *websocket.Conn, filePullRequest fileRequests.FilePullRequest) {

	// Check that file exists
	file, err := GetFileById(filePullRequest.BaseRequest.ResId)
	if err != nil {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-300, filePullRequest.BaseRequest.Tag, nil))
		return
	}

	// Read file from disk
	if _, err := os.Stat(file.GetPath()); os.IsNotExist(err) {
		managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(filePullRequest.BaseRequest.Tag, map[string]interface{}{"FileBytes": "", "Changes": ""}))
		return
	}
	fileBytes, err := ioutil.ReadFile(file.GetPath())
	if err != nil {
		managers.LogError("Failed to read from file", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-301, filePullRequest.BaseRequest.Tag, nil))
		return
	}

	changes, err := GetChangesByFile(file.Id)
	if err != nil {
		managers.LogError("Failed to retrieve changes", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-402, filePullRequest.BaseRequest.Tag, nil))
		return
	}

	managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(filePullRequest.BaseRequest.Tag, map[string]interface{}{"File": file, "FileBytes": fileBytes, "Changes": changes}))
}
func MoveFile(wsConn *websocket.Conn, fileMoveRequest fileRequests.FileMoveRequest) {
	session, collection := managers.GetMGoCollection("Files")
	defer session.Close()

	// Check that file exists
	file, err := GetFileById(fileMoveRequest.BaseRequest.ResId)
	if err != nil {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-300, fileMoveRequest.BaseRequest.Tag, nil))
		return
	}

	file.Version++

	err = collection.Update(bson.M{"_id": fileMoveRequest.BaseRequest.ResId}, bson.M{"$set": bson.M{"relative_path": fileMoveRequest.NewPath, "version": file.Version}})
	if err != nil {
		if mgo.IsDup(err) {
			managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-307, fileMoveRequest.BaseRequest.Tag, nil))
			return
		}
		managers.LogError("Error renaming file", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-303, fileMoveRequest.BaseRequest.Tag, nil))
		return
	}

	managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(fileMoveRequest.BaseRequest.Tag, nil))
	managers.NotifyProjectClients(file.Project, fileMoveRequest.GetNotification(), wsConn)
}
func main() {
	flag.Parse()
	log.SetFlags(0)

	managers.ConnectMGo()
	defer managers.GetPrimaryMGoSession().Close()

	pwd, err := os.Getwd()
	if err != nil {
		managers.LogError("Fatal error: Could not get Working Directory", err)
		log.Fatal(err)
	}
	managers.LogInfo("Running in directory: " + pwd)

	http.HandleFunc("/ws/", handleWSConn)
	http.HandleFunc("/", handleHTTPConn)
	err = http.ListenAndServe(*addr, nil)
	if err != nil {
		managers.LogError("Fatal error: Could not get bind port", err)
		log.Fatal(err)
	}
}
func GetUserByUsername(username string) (*User, error) {
	// Get new DB connection
	session, collection := managers.GetMGoCollection("Users")
	defer session.Close()

	result := new(User)
	err := collection.Find(bson.M{"username": username}).One(&result)
	if err != nil {
		managers.LogError("Failed to retrieve User", err)
		return nil, err
	}

	return result, nil
}
func GetFilesByProjectId(projectId string) ([]File, error) {
	// Get new DB connection
	session, collection := managers.GetMGoCollection("Files")
	defer session.Close()

	var result []File
	err := collection.Find(bson.M{"project": projectId}).All(&result)
	if err != nil {
		managers.LogError("Failed to retrieve Files for project "+projectId, err)
		return nil, err
	}

	return result, nil
}
func GetFileById(id string) (*File, error) {
	// Get new DB connection
	session, collection := managers.GetMGoCollection("Files")
	defer session.Close()

	result := new(File)
	err := collection.Find(bson.M{"_id": id}).One(&result)
	if err != nil {
		managers.LogError("Failed to retrieve File", err)
		return nil, err
	}

	return result, nil
}
func GetChangesByFile(fileId string) ([]FileChange, error) {
	// Get new DB connection
	session, collection := managers.GetMGoCollection("Changes")
	defer session.Close()

	var result []FileChange
	err := collection.Find(bson.M{"file_id": fileId}).Sort("version").All(&result)
	if err != nil {
		managers.LogError("Failed to retrieve FileChanges", err)
		return nil, err
	}

	return result, nil
}
func LoginUser(wsConn *websocket.Conn, loginRequest userRequests.UserLoginRequest) {

	// Get new DB connection
	session, collection := managers.GetMGoCollection("Users")
	defer session.Close()

	user, err := GetUserByUsername(loginRequest.Username)
	if err != nil {
		// Could not find user
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-104, loginRequest.BaseRequest.Tag, nil))
		return
	}

	if err := bcrypt.CompareHashAndPassword([]byte(user.Password_Hash), []byte(loginRequest.Password)); err != nil {
		// Password did not match.
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-104, loginRequest.BaseRequest.Tag, nil))
		return
	}

	tokenBytes, err := bcrypt.GenerateFromPassword([]byte(loginRequest.Username+time.Now().String()), bcrypt.DefaultCost)
	if err != nil {
		managers.LogError("Failed to generate token", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-103, loginRequest.BaseRequest.Tag, nil))
		return
	}

	token := string(tokenBytes[:])

	err = addToken(collection, user, token)
	if err != nil {
		managers.LogError("Failed to save token", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-103, loginRequest.BaseRequest.Tag, nil))
		return
	}

	managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(loginRequest.BaseRequest.Tag, map[string]interface{}{"Token": token}))
}
func goScrunchDB(fileID string) {

	cmd := exec.Command("java", "-jar", "Scrunching.jar", fileID)
	err := cmd.Start()
	err = cmd.Wait()
	if err != nil {
		var message string
		switch err.Error() {
		case "exit status 60":
			message = "scrunchDB: Improper number of arguments" // will never get here
			managers.LogWarn(message)
		case "exit status 61":
			message = "scrunchDB: File not found in db with fileID: " + fileID
			managers.LogWarn(message)
			return
		case "exit status 62":
			message = "File not found on disk " + fileID
			managers.LogWarn(message)
			//			return correctFileNotFound(fileID)
		case "exit status 63":
			message = "scrunchDB: Unknown error while reading file: " + fileID
			managers.LogError(message, err)
		case "exit status 64":
			message = "scrunchDB: Can't apply patch for fileID" + fileID + ": Run Scrunching.jar directly to get bad patch key"
			//TODO: figure out if there's a way to get patch key from Scrunching.java @ line 103
			managers.LogError(message, err)
		case "exit status 65":
			message = "scrunchDB: Unable to compile patch for filID: " + fileID
			//TODO: figure out if there's a way to get patch key from Scrunching.java @ line 158
			managers.LogError(message, err)
		default:
			return
		}

		return
	}
}
func handleWSConn(responseWriter http.ResponseWriter, request *http.Request) {
	if request.URL.Path != "/ws/" {
		http.Error(responseWriter, "Not found", 404)
		return
	}
	if request.Method != "GET" {
		http.Error(responseWriter, "Method not allowed", 405)
		return
	}
	wsConn, err := upgrader.Upgrade(responseWriter, request, nil)
	if err != nil {
		managers.LogError("Failed to upgrade connection:", err)
		return
	}

	defer wsConn.Close()
	defer managers.WebSocketDisconnected(wsConn)
	// move above adding it to the web socket structure in case adding it fails part way through

	// subscriptions moved to User Subscribe request
	// managers.NewWebSocketConnected(wsConn)

	for {
		// messageType, message, err := wsConn.ReadMessage()
		_, message, err := wsConn.ReadMessage()
		if err != nil {
			managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(0, 0, nil))
			break
		}

		// Deserialize data from json.
		var baseRequestObj baseRequests.BaseRequest
		if err := json.Unmarshal(message, &baseRequestObj); err != nil {

			managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, map[string]interface{}{"Error:": err}))

		} else {
			if !("User" == baseRequestObj.Resource && ("Register" == baseRequestObj.Action || "Login" == baseRequestObj.Action)) && !userModels.CheckUserAuth(baseRequestObj) {
				managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-105, baseRequestObj.Tag, nil))
			} else {

				if !(baseRequestObj.Resource == "User" && ("Login" == baseRequestObj.Action || "Register" == baseRequestObj.Action)) {
					managers.LogAccess(baseRequestObj, string(message))
				}

				switch baseRequestObj.Resource {
				case "Project":
					switch baseRequestObj.Action {
					case "GetPermissionLevels":
						// {"Resource":"Project", "Action":"GetPermissionLevels", "Username":"******", "Token": "test"}
						// Deserialize from JSON
						var projectGetPermissionLevelsRequest projectRequests.ProjectGetPermissionLevelsRequest
						if err := json.Unmarshal(message, &projectGetPermissionLevelsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectGetPermissionLevelsRequest.BaseRequest = baseRequestObj
						projectModels.GetPermissionLevels(wsConn, projectGetPermissionLevelsRequest)

					case "Create":

						// {"Resource":"Project", "Action":"Create", "Username":"******", "Token": "$2a$10$kWgnc1TcG.KBaGH0cjY52OzWYt77XvkGRtOpim6ISD/W8avdujeTO", "Name":"foo"}
						// Deserialize from JSON
						var projectCreateRequest projectRequests.ProjectCreateRequest
						if err := json.Unmarshal(message, &projectCreateRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectCreateRequest.BaseRequest = baseRequestObj
						projectModels.CreateProject(wsConn, projectCreateRequest)

					case "Rename":

						// {"Resource":"Project", "Action":"Rename", "ResId": "561987174357413b14000002", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e", "NewName":"bar"}
						// Deserialize from JSON
						var projectRenameRequest projectRequests.ProjectRenameRequest
						if err := json.Unmarshal(message, &projectRenameRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectRenameRequest.BaseRequest = baseRequestObj
						projectModels.RenameProject(wsConn, projectRenameRequest)

					case "GrantPermissions":

						// {"Resource":"Project", "Action":"GrantPermissions", "ResId": "561987174357413b14000002", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e", "GrantUsername":"******", "PermissionLevel":5}
						// Deserialize from JSON
						var projectGrantPermissionsRequest projectRequests.ProjectGrantPermissionsRequest
						if err := json.Unmarshal(message, &projectGrantPermissionsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectGrantPermissionsRequest.BaseRequest = baseRequestObj

						projectModels.GrantProjectPermissions(wsConn, projectGrantPermissionsRequest)

					case "RevokePermissions":

						// {"Resource":"Project", "Action":"RevokePermissions", "ResId": "561987174357413b14000002", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e", "RevokeUsername":"******"}
						// Deserialize from JSON
						var projectRevokePermissionsRequest projectRequests.ProjectRevokePermissionsRequest
						if err := json.Unmarshal(message, &projectRevokePermissionsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectRevokePermissionsRequest.BaseRequest = baseRequestObj

						projectModels.RevokeProjectPermissions(wsConn, projectRevokePermissionsRequest)

					case "GetSubscribedClients":

						// {"Resource":"Project", "Action":"GetSubscribedClients", "ResId": "561987174357413b14000002", "Username":"******", "Token": "test"}
						// Deserialize from JSON
						var projectGetSubscribedClientsRequest projectRequests.ProjectGetSubscribedClientsRequest
						if err := json.Unmarshal(message, &projectGetSubscribedClientsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectGetSubscribedClientsRequest.BaseRequest = baseRequestObj

						managers.GetSubscribedClients(wsConn, projectGetSubscribedClientsRequest)

					case "GetCollaborators":

						// {"Resource":"Project", "Action":"GetCollaborators", "ResId": "561987174357413b14000002", "Username":"******", "Token": "test"}
						// Deserialize from JSON
						var ProjectGetCollaboratorsRequest projectRequests.ProjectGetCollaboratorsRequest
						if err := json.Unmarshal(message, &ProjectGetCollaboratorsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						ProjectGetCollaboratorsRequest.BaseRequest = baseRequestObj

						projectModels.GetCollaborators(wsConn, ProjectGetCollaboratorsRequest)

					case "GetFiles":

						// {"Resource":"Project", "Action":"GetFiles", "ResId": "561987174357413b14000002", "Username":"******", "Token": "token-fahslaj"}
						var projectFilesRequest projectRequests.ProjectGetFilesRequest
						if err := json.Unmarshal(message, &projectFilesRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectFilesRequest.BaseRequest = baseRequestObj

						projectModels.GetFiles(wsConn, projectFilesRequest)

					case "Subscribe":

						// {"Resource":"Project", "Action":"Subscribe", "Projects":["5629a063111aeb63cf000001"], "Username":"******", "Token": "token-fahslaj"}
						var projectSubscribeRequest projectRequests.ProjectSubscribeRequest
						if err := json.Unmarshal(message, &projectSubscribeRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectSubscribeRequest.BaseRequest = baseRequestObj

						projectModels.Subscribe(wsConn, projectSubscribeRequest)

					case "Unsubscribe":

						// {"Resource":"Project", "Action":"Unsubscribe", "Projects":["5629a063111aeb63cf000001"], "Username":"******", "Token": "token-fahslaj"}
						var projectUnsubscribeRequest projectRequests.ProjectUnsubscribeRequest
						if err := json.Unmarshal(message, &projectUnsubscribeRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						projectUnsubscribeRequest.BaseRequest = baseRequestObj

						projectModels.Unsubscribe(wsConn, projectUnsubscribeRequest)

					case "Delete":
					// TODO

					default:
						managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-3, baseRequestObj.Tag, nil))
						break
					}
				case "File":
					switch baseRequestObj.Action {

					case "Create":
						// {"Resource":"File", "Action":"Create", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e", "Name":"foo", "RelativePath":"test/path1/", "ProjectId":"561987174357413b14000002"}
						// Deserialize from JSON
						var fileCreateRequest fileRequests.FileCreateRequest
						if err := json.Unmarshal(message, &fileCreateRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						fileCreateRequest.BaseRequest = baseRequestObj
						fileModels.CreateFile(wsConn, fileCreateRequest)

					case "Rename":
						// {"Resource":"File", "Action":"Rename", "ResId":"561987a84357413b14000006", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e", "NewName":"foo2"}
						// Deserialize from JSON
						var fileRenameRequest fileRequests.FileRenameRequest
						if err := json.Unmarshal(message, &fileRenameRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						fileRenameRequest.BaseRequest = baseRequestObj
						fileModels.RenameFile(wsConn, fileRenameRequest)

					case "Move":
						// {"Resource":"File", "Action":"Move", "ResId":"561987a84357413b14000006", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e", "NewPath":"test/path2/"}
						// Deserialize from JSON
						var fileMoveRequest fileRequests.FileMoveRequest
						if err := json.Unmarshal(message, &fileMoveRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						fileMoveRequest.BaseRequest = baseRequestObj
						fileModels.MoveFile(wsConn, fileMoveRequest)

					case "Delete":
						// {"Resource":"File", "Action":"Delete", "ResId":"561987a84357413b14000006", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e"}
						// Deserialize from JSON
						var fileDeleteRequest fileRequests.FileDeleteRequest
						if err := json.Unmarshal(message, &fileDeleteRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						fileDeleteRequest.BaseRequest = baseRequestObj
						fileModels.DeleteFile(wsConn, fileDeleteRequest)

					case "Change":
						// {"Tag": 112, "Action": "Change", "Resource": "File", "ResId": "561987a84357413b14000006", "FileVersion":0, "Changes": "@@ -40,16 +40,17 @@\n almost i\n+t\n n shape", "Username":"******", "Token": "$2a$10$gifm6Vrfn2vBBCX7qvaQzu.Pvttotyu1pRW5V6X7RnhYYiQCUHh4e"}
						// Deserialize from JSON
						var fileChangeRequest fileRequests.FileChangeRequest
						if err := json.Unmarshal(message, &fileChangeRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						fileChangeRequest.BaseRequest = baseRequestObj

						fileModels.InsertChange(wsConn, fileChangeRequest)

					case "Pull":
						// {"Tag": 112, "Action": "Pull", "Resource": "File", "ResId": "5629a0c2111aeb63cf000002", "Username":"******", "Token": "token-fahslaj"}
						// Deserialize from JSON
						var filePullRequest fileRequests.FilePullRequest
						if err := json.Unmarshal(message, &filePullRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						filePullRequest.BaseRequest = baseRequestObj

						fileModels.PullFile(wsConn, filePullRequest)

					case "Projects":

						// {"Resource":"User", "Action":"Projects", "Username":"******", "Token": "token-fahslaj"}
						var userProjectsRequest userRequests.UserProjectsRequest
						if err := json.Unmarshal(message, &userProjectsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						userProjectsRequest.BaseRequest = baseRequestObj

						userModels.UserProjects(wsConn, userProjectsRequest)

					default:
						baseModels.NewFailResponse(-3, baseRequestObj.Tag, map[string]interface{}{"Action": baseRequestObj.Action})
						break
					}

				// // Notify success; return new version number.
				// base.NewSuccessResponse(baseRequestObj.Tag, nil)

				case "User":
					switch baseRequestObj.Action {
					case "Register":

						// {"Resource":"User", "Action":"Register", "Username":"******", "Password":"******"}
						// Deserialize from JSON
						var userRegisterRequest userRequests.UserRegisterRequest
						if err := json.Unmarshal(message, &userRegisterRequest); err != nil {

							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						userRegisterRequest.BaseRequest = baseRequestObj

						userModels.RegisterUser(wsConn, userRegisterRequest)
					case "Login":

						// {"Resource":"User", "Action":"Login", "Username":"******", "Password":"******"}
						// Deserialize from JSON
						var userLoginRequest userRequests.UserLoginRequest
						if err := json.Unmarshal(message, &userLoginRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						userLoginRequest.BaseRequest = baseRequestObj

						//Check username/pw, login if needed.
						userModels.LoginUser(wsConn, userLoginRequest)

					case "Lookup":

						// {"Resource":"User", "Action":"Lookup", "LookupUsername":"******", "Username":"******", "Token": "token-fahslaj"}
						var userLookupRequest userRequests.UserLookupRequest
						if err := json.Unmarshal(message, &userLookupRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						userLookupRequest.BaseRequest = baseRequestObj

						userModels.LookupUser(wsConn, userLookupRequest)

					case "Projects":

						// {"Resource":"User", "Action":"Projects", "Username":"******", "Token": "token-fahslaj"}
						var userProjectsRequest userRequests.UserProjectsRequest
						if err := json.Unmarshal(message, &userProjectsRequest); err != nil {
							managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-1, baseRequestObj.Tag, nil))
							break
						}
						// Add BaseRequest reference
						userProjectsRequest.BaseRequest = baseRequestObj

						userModels.UserProjects(wsConn, userProjectsRequest)

					//TODO: maybe delete?

					//TODO: Change PW

					default:
						managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-3, baseRequestObj.Tag, nil))
						break
					}
				default:
					// Invalid resource type
					managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-2, baseRequestObj.Tag, nil))
					break
				}
			}
		}
	}
}
Пример #11
0
func RegisterUser(wsConn *websocket.Conn, registrationRequest userRequests.UserRegisterRequest) {

	matched, err := regexp.MatchString("^[\\w]+$", registrationRequest.Username)
	if !matched {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-106, registrationRequest.BaseRequest.Tag, nil))
		return
	}

	// Hash password using bcrypt
	pwHashBytes, err := bcrypt.GenerateFromPassword([]byte(registrationRequest.Password), bcrypt.DefaultCost)
	if err != nil {
		managers.LogError("Failed to hash password", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-101, registrationRequest.BaseRequest.Tag, nil))
		return
	}

	// Create new UserAuthData object
	userAuthData := new(User)
	userAuthData.Id = managers.NewObjectIdString()
	userAuthData.FirstName = registrationRequest.FirstName
	userAuthData.LastName = registrationRequest.LastName
	userAuthData.Username = registrationRequest.Username
	userAuthData.Email = registrationRequest.Email
	userAuthData.Password_Hash = string(pwHashBytes[:])

	// Get new DB connection
	session, collection := managers.GetMGoCollection("Users")
	defer session.Close()

	// Make sure email is unique
	index := mgo.Index{
		Key:        []string{"email"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err = collection.EnsureIndex(index)
	if err != nil {
		managers.LogError("Failed to ensure email index", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-101, registrationRequest.BaseRequest.Tag, nil))
		return
	}

	// Make sure username is unique
	index = mgo.Index{
		Key:        []string{"username"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err = collection.EnsureIndex(index)
	if err != nil {
		managers.LogError("Failed to ensure username index", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-101, registrationRequest.BaseRequest.Tag, nil))
		return
	}

	// Register new user
	err = collection.Insert(userAuthData)
	if err != nil {
		// Duplicate entry
		if mgo.IsDup(err) {
			managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-102, registrationRequest.BaseRequest.Tag, nil))
			return
		}
		managers.LogError("Error registering user", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-101, registrationRequest.BaseRequest.Tag, nil))
		return
	}

	managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(registrationRequest.BaseRequest.Tag, nil))
}
Пример #12
0
func CreateFile(wsConn *websocket.Conn, fileCreateRequest fileRequests.FileCreateRequest) {

	file := new(File)
	file.Id = managers.NewObjectIdString()
	file.Name = fileCreateRequest.Name
	file.RelativePath = fileCreateRequest.RelativePath
	file.Version = 0
	file.Project = fileCreateRequest.ProjectId

	session, collection := managers.GetMGoCollection("Files")
	defer session.Close()

	// Create indexes
	index := mgo.Index{
		Key:        []string{"name", "relative_path"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err := collection.EnsureIndex(index)
	if err != nil {
		managers.LogError("Failed to ensure file name/path index", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-301, fileCreateRequest.BaseRequest.Tag, nil))
		return
	}

	// Insert file record
	err = collection.Insert(file)
	if err != nil {
		if mgo.IsDup(err) {
			managers.LogError("Error creating file record", err)
			managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-305, fileCreateRequest.BaseRequest.Tag, nil))
			return
		}
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-301, fileCreateRequest.BaseRequest.Tag, nil))
		return
	}

	// Write file to disk

	fileCreateRequest.RelativePath = filepath.Clean(fileCreateRequest.RelativePath)
	if fileCreateRequest.RelativePath[0:2] == ".." || filepath.IsAbs(fileCreateRequest.RelativePath) {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-308, fileCreateRequest.BaseRequest.Tag, nil))
		return
	}

	err = os.MkdirAll("files/"+fileCreateRequest.ProjectId+"/"+fileCreateRequest.RelativePath, os.ModeExclusive)
	if err != nil {
		managers.LogError("Failed to create file directory", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-301, fileCreateRequest.BaseRequest.Tag, nil))
		return
	}
	err = ioutil.WriteFile(file.GetPath(), fileCreateRequest.FileBytes, os.ModeExclusive)
	if err != nil {
		managers.LogError("Failed to write file", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-301, fileCreateRequest.BaseRequest.Tag, nil))
		return
	}

	managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(fileCreateRequest.BaseRequest.Tag, map[string]interface{}{"FileId": file.Id}))
	managers.NotifyProjectClients(file.Project, fileCreateRequest.GetNotification(file.Id), wsConn)
}
func InsertChange(wsConn *websocket.Conn, fileChangeRequest fileRequests.FileChangeRequest) {

	// Check that file exists
	file, err := GetFileById(fileChangeRequest.BaseRequest.ResId)
	if err != nil {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-300, fileChangeRequest.BaseRequest.Tag, nil))
		return
	}

	// Check that user is on latest version, then increment. Otherwise, throw error
	if fileChangeRequest.FileVersion < file.Version {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-401, fileChangeRequest.BaseRequest.Tag, nil))
		return
	}
	fileChangeRequest.FileVersion++

	fileChange := new(FileChange)
	fileChange.Id = managers.NewObjectIdString()
	fileChange.Changes = fileChangeRequest.Changes
	fileChange.FileId = fileChangeRequest.BaseRequest.ResId
	fileChange.Version = fileChangeRequest.FileVersion
	fileChange.Username = fileChangeRequest.BaseRequest.Username
	fileChange.Date = time.Now().UTC()

	changesSession, changesCollection := managers.GetMGoCollection("Changes")
	defer changesSession.Close()

	index := mgo.Index{
		Key:        []string{"file", "version"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err = changesCollection.EnsureIndex(index)
	if err != nil {
		managers.LogError("Failed to ensure changes index", err)
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-400, fileChangeRequest.BaseRequest.Tag, nil))
	}

	err = changesCollection.Insert(fileChange)
	if err != nil {
		if mgo.IsDup(err) {
			managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-401, fileChangeRequest.BaseRequest.Tag, nil))
			return
		}
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-400, fileChangeRequest.BaseRequest.Tag, nil))
		return
	}

	filesSession, filesCollection := managers.GetMGoCollection("Files")
	defer filesSession.Close()
	err = filesCollection.Update(bson.M{"_id": fileChangeRequest.BaseRequest.ResId}, bson.M{"$set": bson.M{"version": fileChangeRequest.FileVersion}})
	if err != nil {
		managers.SendWebSocketMessage(wsConn, baseModels.NewFailResponse(-400, fileChangeRequest.BaseRequest.Tag, nil))
		return
	}

	// TODO: Change when fileVersion is changed to atomic int
	if fileChange.Version%100 == 0 {
		scrunching.ScrunchDB(fileChange.FileId)
	}

	managers.SendWebSocketMessage(wsConn, baseModels.NewSuccessResponse(fileChangeRequest.BaseRequest.Tag, map[string]interface{}{"FileVersion": fileChangeRequest.FileVersion}))
	managers.NotifyProjectClients(file.Project, fileChangeRequest.GetNotification(fileChangeRequest.FileVersion), wsConn)
}