func deleteSourceFiles(s session.Store, fileNames []string, projectNames []string) Data { // if user is not logged in return if s.Get("UserName") == nil { return Data{} } name := s.Get("UserName").(string) dir := beego.AppConfig.String("userdata::location") + name for i := 0; i < len(fileNames); i++ { ///////////////////////////////////////// // Remove js and png file fileType := fileNames[i][strings.LastIndex(fileNames[i], ".")+1:] var fileName string if projectNames != nil && projectNames[i] != "" { fileName = dir + "/" + beego.AppConfig.String("userdata::projects") + "/" + projectNames[i] + "/" + fileType + "/" + fileNames[i] } else { fileName = dir + "/" + fileType + "/" + fileNames[i] } if err := os.Remove(fileName); err != nil { beego.Error("Cannot remove file", fileName, "(", err.Error(), ")") } fileName = fileName[:strings.LastIndex(fileName, ".")] + ".png" if err := os.Remove(fileName); err != nil { beego.Error("Cannot remove file", fileName, "(", err.Error(), ")") } } return Data{} }
func readNewMessages(s session.Store, messageIds []int64) Data { userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { beego.Error("No user name available.") return Data{} } messages := models.GetMessagesFromDatabase(userName) for i := len(messages) - 1; i >= 0; i-- { beego.Warning(len(messages), i) for j := 0; j < len(messageIds); j++ { beego.Warning(messages[i], j, messageIds[j]) if messages[i]["Id"] == messageIds[j] { messages = append(messages[:i], messages[i+1:]...) break } } } return Data{ "Messages": messages, } }
func cloneProject(s session.Store, projectName string) Data { // if user is not logged in return userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { beego.Error("No user name available.") return Data{} } beego.Warning("Entering cloneProject with", userName, "and", projectName) if projectName == "" { beego.Error("No project name available.") return Data{} } // Check for rights // Maybe add a token check here, otherwise manipulated clients can clone any project models.CloneProjectDir(userName, projectName, false) return Data{ "ProjectName": projectName, } }
func readPals(s session.Store) Data { // Read own groups userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { beego.Error("No user name available.") return Data{} } return Data{ "Pals": models.GetPalsFromDatabase(userName), } }
func getStatus(s session.Store) Data { userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { return Data{ "Status": "No session", } } else { return Data{ "Status": "Ok", } } }
func sendInvitations(s session.Store, projectName string, userNames []string) Data { T := models.T userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { beego.Error("No user name available.") return Data{} } models.CreateInvitationMessages(userName, projectName, userNames, T["project_bar_modal_invite_subject"], T["project_bar_modal_invite_message"]) return Data{} }
func fetchProject(s session.Store, projectName string) (Data, error) { // if user is not logged in return userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { return Data{}, errors.New("No user name available.") } if projectName == "" { return Data{}, errors.New("No project name available.") } userDir := beego.AppConfig.String("userdata::location") + userName projectDir := userDir + "/" + beego.AppConfig.String("userdata::projects") + "/" + projectName // 1 Open repository repo, err := git.OpenRepository(projectDir) if err != nil { return Data{}, errors.New("OpenRepository - " + err.Error()) } // 2 Create a signature sig := &git.Signature{ Name: userName, Email: userName + "@" + beego.AppConfig.String("userdata::emailserver"), When: time.Now(), } err = models.AnnotatedPull(repo, sig) if err != nil { if strings.Index(err.Error(), "uncommitted change") != -1 { e := errors.New("uncommitted changes") return Data{ "Error": e.Error(), }, e } return Data{ "Error": err.Error(), }, err } return Data{}, nil }
func deleteMessage(s session.Store, messageId int64) Data { userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { beego.Error("No user name available.") return Data{} } err := models.DeleteMessageFromDatabase(userName, messageId) if err == nil { return Data{} } else { return Data{ "Error": err.Error(), } } }
func renameSourceFile(s session.Store, fileNames []string, fileType string) Data { // if user is not logged in return if s.Get("UserName") == nil { return Data{} } name := s.Get("UserName").(string) dir := beego.AppConfig.String("userdata::location") + name + "/" + fileType + "/" _, err := os.Stat(dir + "/" + fileNames[1]) if !os.IsNotExist(err) { return Data{ "Error": "file exists", } } err = os.Rename(dir+"/"+fileNames[0], dir+"/"+fileNames[1]) if err != nil { return Data{ "Error": "cannot rename file", } } // Also rename associated pngs for i := 0; i < 2; i++ { fileNames[i] = fileNames[i][:strings.LastIndex(fileNames[i], ".")] + ".png" } beego.Warning("Renaming", fileNames[0], "to", fileNames[1]) err = os.Rename(dir+"/"+fileNames[0], dir+"/"+fileNames[1]) if err != nil { return Data{ "Error": "cannot rename file", } } return Data{} }
func GetUserIdFromSession(sess session.Store) int { if id, ok := sess.Get("auth_user_id").(int); ok && id > 0 { return id } return 0 }
func writeProject(s session.Store, projectName string, fileType string, fileName string, codeFile string, timeStamp int64, resourceFiles []string, image string, alternateFile string, alternateType string, commit string) Data { // if user is not logged in return userName := "" if s.Get("UserName") != nil { userName = s.Get("UserName").(string) } if userName == "" { beego.Error("No user name available.") return Data{} } if projectName == "" { beego.Error("No project name available.") return Data{} } // Check for rights if ok := models.CheckRight(userName, projectName, "Write"); !ok { return Data{ "Error": "Unsufficient rights for project " + projectName + ".", } } userDir := beego.AppConfig.String("userdata::location") + userName projectDir := userDir + "/" + beego.AppConfig.String("userdata::projects") + "/" + projectName // Write source files to new project directory data := writeSourceFile(s, fileName, projectName, fileType, codeFile, timeStamp, image, alternateFile, alternateType, true) outdatedFile := data["OutdatedFile"] if outdatedFile != nil && outdatedFile.(string) != "" { return data } // Copy resource files for i := 0; i < len(resourceFiles); i++ { resProject := resourceFiles[i][:strings.Index(resourceFiles[i], "/")] resType := resourceFiles[i][strings.LastIndex(resourceFiles[i], ".")+1:] filename := resourceFiles[i][strings.LastIndex(resourceFiles[i], "/")+1:] dir := "." if resProject == projectName { continue } switch resType { case "png": dir = beego.AppConfig.String("userdata::imagefiles") case "mp3": dir = beego.AppConfig.String("userdata::soundfiles") } err := copyFileContents(userDir+"/"+dir+"/"+resourceFiles[i], projectDir+"/"+dir+"/"+filename) if err != nil { beego.Error("Cannot copy resource file", resourceFiles[i], "from", userDir, "to", projectDir, "(", err.Error(), ")") } } // Add, commit and push if err := models.GitAddCommitPush(userName, projectDir, commit, false); err != nil { if err.Error() == "Conflicts" { data["Conflicts"] = "Solve conflicts." } else { beego.Error("Add, commit, push: ", err.Error()) } } return data }
func initProject(s session.Store, projectName string, fileType string, fileName string, codeFile string, resourceFiles []string, image string) Data { // if user is not logged in return if s.Get("UserName") == nil { beego.Error("No user name available.") return Data{} } if projectName == "" { beego.Error("No project name available.") return Data{} } userName := s.Get("UserName").(string) userDir := beego.AppConfig.String("userdata::location") + userName projectDir := userDir + "/" + beego.AppConfig.String("userdata::projects") + "/" + projectName bareDir := beego.AppConfig.String("userdata::location") + beego.AppConfig.String("userdata::bareprojects") + "/" + projectName ////////////////////////////////////////////////////////////////////7 // Everything, that has to be done for init a project _, err := os.Stat(bareDir) if !os.IsNotExist(err) { return Data{ "Error": "project exists", } } // Create new directory if err := os.MkdirAll(bareDir, os.ModePerm); err != nil { beego.Error("Cannot create directory", bareDir) } // Initialize as bare git directory _, err = git.InitRepository(bareDir, true) if err != nil { beego.Error("Cannot init git directory", bareDir, "(", err.Error(), ")") } // Clone it to own project directory options := git.CloneOptions{ Bare: false, } _, err = git.Clone(bareDir, projectDir, &options) if err != nil { beego.Error("Cannot clone git directory", bareDir, "into", projectDir, "(", err.Error(), ")") } // err = models.GitSetName(userName, userName+"@"+beego.AppConfig.String("userdata::emailserver")) // Create project directories models.CreateDirectories(projectDir, false) // Create .gitignore file with .spielplatz/project in it models.CreateTextFile(projectDir+"/"+".gitignore", beego.AppConfig.String("userdata::spielplatzdir")+"/rights") // Copy resource files for i := 0; i < len(resourceFiles); i++ { resType := resourceFiles[i][strings.LastIndex(resourceFiles[i], ".")+1:] filename := resourceFiles[i][strings.LastIndex(resourceFiles[i], "/")+1:] dir := "." switch resType { case "png": dir = beego.AppConfig.String("userdata::imagefiles") case "mp3": dir = beego.AppConfig.String("userdata::soundfiles") } err = copyFileContents(userDir+"/"+dir+"/"+resourceFiles[i], projectDir+"/"+dir+"/"+filename) if err != nil { beego.Error("Cannot copy resource file", resourceFiles[i], "from", userDir, "to", projectDir, "(", err.Error(), ")") } } // Mount resource directories models.MountResourceFiles(userName, projectName) // Create project config file projectFile := projectDir + "/" + beego.AppConfig.String("userdata::spielplatzdir") + "/project" file, err := os.Create(projectFile) if err != nil { beego.Error(err) } file.Close() cnf, err := config.NewConfig("ini", projectFile) if err != nil { beego.Error("Cannot create project file " + projectFile + " (" + err.Error() + ")") } cnf.Set("Playground", beego.AppConfig.String("userdata::name")) cnf.Set("Origin", "none") cnf.Set("Gallery", "false") cnf.SaveConfigFile(projectFile) // Create rights file rightsFile := projectDir + "/" + beego.AppConfig.String("userdata::spielplatzdir") + "/rights" file, err = os.Create(rightsFile) if err != nil { beego.Error(err) } file.Close() cnf, err = config.NewConfig("ini", rightsFile) if err != nil { beego.Error("Cannot create rights file " + rightsFile + " (" + err.Error() + ")") } for _, right := range models.PRR_NAMES { cnf.Set("rights::"+right, "true") } cnf.SaveConfigFile(rightsFile) // Create database entry user, _ := models.GetUser(userName) project := new(models.Project) project.Name = projectName project.Playground = beego.AppConfig.String("userdata::name") project.Origin = "none" project.Gallery = false project.Forks = 0 project.Stars = 0 models.CreateProjectDatabaseEntry(project, user, int64(1<<uint(len(models.PRR_NAMES)))-1) // Write source files to new project directory name := projectName + "." + fileType data := writeSourceFile(s, name, projectName, fileType, codeFile, int64(0), image, "", "", false) // Add all rights as return values data["Rights"] = models.PRR_NAMES // Only one user by now data["Users"] = []string{userName} // Add, commit and push err = models.GitAddCommitPush(userName, projectDir, beego.AppConfig.String("userdata::firstcommit"), true) if err != nil { beego.Error(err) } // Remove old files, if any if fileName != "" { deleteSourceFiles(s, []string{fileName}, nil) } return data }
func readDir(s session.Store, fileType string) Data { data := Data{} sourceFiles := make(map[string]SourceFile) projectNames := make([]string, 1, models.MaxProjectsPerUser) projectNames[0] = "/" userName := s.Get("UserName") // if user is not logged in return if userName == nil { return data } // First search in the main directory name := userName.(string) dir := beego.AppConfig.String("userdata::location") + name + "/" + fileType files, err := ioutil.ReadDir(dir) if os.IsNotExist(err) { beego.Warning("Directory", dir, "is not available.") } else if err != nil { beego.Error(err) return data } for _, f := range files { name := f.Name() if name[len(name)-len(fileType):] == fileType { sourceFiles[name] = SourceFile{ TimeStamp: f.ModTime().UnixNano() / int64(time.Millisecond), Project: "", } } } // Then read all projects and look into the dir of the specified filetype (e.g. pjs) dir = beego.AppConfig.String("userdata::location") + name + "/" + beego.AppConfig.String("userdata::projects") projects, err := ioutil.ReadDir(dir) if err != nil { beego.Error(err) return data } for _, p := range projects { var dir2 string if p.IsDir() == true { project := p.Name() dir2 = dir + "/" + p.Name() + "/" + fileType files, err := ioutil.ReadDir(dir2) if os.IsNotExist(err) { beego.Warning("Directory", dir2, "is not available.") } else if err != nil { beego.Error(err) return data } for _, f := range files { name := f.Name() if name[len(name)-len(fileType):] == fileType { sourceFiles[name] = SourceFile{ TimeStamp: f.ModTime().UnixNano() / int64(time.Millisecond), Project: project, } } } } } projectNames = append(projectNames, models.GetProjectsWithRightFromDatabase(name, "Write")...) data["Files"] = sourceFiles data["Projects"] = projectNames return data }
func readSourceFiles(s session.Store, fileNames []string, fileProjects []string, fileType string) Data { // if user is not logged in return if s.Get("UserName") == nil { return Data{} } name := s.Get("UserName").(string) dir := beego.AppConfig.String("userdata::location") + name + "/" codeFiles := make(map[string]SourceFile) for i := 0; i < len(fileNames); i++ { var ( file *os.File err error ) ///////////////////////////////////////// // Fetch project project := fileProjects[i] status := STATUS_OK if project != "" { _, err := fetchProject(s, project) if err != nil { switch err.Error() { case "uncommitted changes": beego.Warning("Uncommitted changes detected with project", "for user", name) status = STATUS_UNCOMMITTED } } } ///////////////////////////////////////// // Read file var fileName string if project != "" { fileName = dir + beego.AppConfig.String("userdata::projects") + "/" + project + "/" + fileType + "/" + fileNames[i] } else { fileName = dir + fileType + "/" + fileNames[i] } if file, err = os.Open(fileName); err != nil { beego.Error("Cannot open file", fileName) return Data{} } defer file.Close() fileInfo, _ := file.Stat() fileSize := fileInfo.Size() codeFile := make([]byte, fileSize) _, err = file.Read(codeFile) if err != nil { beego.Error("Read error occured.") return Data{} } rights := []string{} users := []string{} if project != "" { rights = models.GetProjectRightsFromDatabase(name, project) users = models.GetProjectUsersFromDatabase(project) } codeFiles[fileNames[i]] = SourceFile{ TimeStamp: fileInfo.ModTime().UnixNano() / int64(time.Millisecond), Code: string(codeFile), Project: project, Rights: rights, Users: users, Status: status, } } return Data{ "CodeFiles": codeFiles, } }
func writeSourceFile(s session.Store, fileName string, project string, fileType string, codeFile string, timeStamp int64, Image string, alternateFile string, alternateType string, overwrite bool) Data { // if user is not logged in return if s.Get("UserName") == nil { return Data{} } T := models.T userName := s.Get("UserName").(string) if project == "/" { project = "" } //////////////////////////////////////// // Retrieve rights and users if it is a project rights := []string{} users := []string{} if project != "" { rights = models.GetProjectRightsFromDatabase(userName, project) users = models.GetProjectUsersFromDatabase(project) beego.Warning("writeSourceFile:", userName, project, rights, users) } if project != "" && !models.CheckRight(userName, project, "Write") { return Data{ "Error": "Insufficient rights for project " + project, } } var dir string if project != "" { dir = beego.AppConfig.String("userdata::location") + userName + "/" + beego.AppConfig.String("userdata::projects") + "/" + project + "/" + fileType + "/" } else { dir = beego.AppConfig.String("userdata::location") + userName + "/" + fileType + "/" } var ( file *os.File err error savedTimeStamp int64 ) filePath := dir + fileName ///////////////////////////////////////// // Check if directory is there and create if not // fileStat, err := os.Stat(filePath) if os.IsNotExist(err) { if err = os.MkdirAll(dir, os.ModePerm); err != nil { beego.Error("Cannot create directory", dir) return Data{} } } else if err != nil { beego.Error("Error while checking for directory", dir) return Data{} } ///////////////////////////////////////// // Don't overwrite file unintendedly fileStat, err = os.Stat(filePath) if !overwrite { if !os.IsNotExist(err) { return Data{ "Error": T["websockets_file_exists"], } } else if err == nil { time := fileStat.ModTime().UnixNano() / int64(time.Millisecond) // Look if the file changed on disk since last writing if time > timeStamp { return Data{ "OutdatedTimeStamp": time, } } } } ///////////////////////////////////////// // Also check if alternate file type (png, mp3) would be overwritten altSubDir := "" switch alternateType { case "png": altSubDir = beego.AppConfig.String("userdata::imagefiles") case "mp3": altSubDir = beego.AppConfig.String("userdata::soundfiles") } altDir := dir[:len(dir)-len(fileType)-1] + altSubDir + "/" altFileName := altDir + fileName[:len(fileName)-len(fileType)] + alternateType if alternateType != "" { fileStat, err = os.Stat(altFileName) if !overwrite { if !os.IsNotExist(err) { return Data{ "Error": T["websockets_file_exists"], } } } } beego.Warning("altDir:", altDir, "altFileName:", altFileName) ///////////////////////////////////////// // Create/overwrite file if file, err = os.Create(filePath); err != nil { beego.Error("Cannot create or overwrite file", filePath) return Data{} } defer file.Close() _, err = file.Write([]byte(codeFile)) //////////////////////////////////////// // Record timestamps for web app if err == nil { fileStat, _ = file.Stat() savedTimeStamp = fileStat.ModTime().UnixNano() / int64(time.Millisecond) } else { beego.Error("Cannot write to file", filePath) return Data{} } //////////////////////////////////////// // Create image file createImageFile(Image, filePath) if alternateType == "png" { createImageFile(alternateFile, altFileName) } else if alternateType == "mp3" { // create sound file } return Data{ "SavedTimeStamp": savedTimeStamp, "Rights": rights, "Users": users, } }
func (this *BaseController) GetUserIdFromSession(sess session.Store) int64 { if id, ok := sess.Get("auth_user_id").(int64); ok && id > 0 { return id } return 0 }