// ApproveLabHandler is a http handler used by teachers to approve a lab. func ApproveLabHandler(w http.ResponseWriter, r *http.Request) { // Checks if the user is signed in and a teacher. member, err := checkTeacherApproval(w, r, true) if err != nil { log.Println(err) return } course := r.FormValue("Course") username := r.FormValue("User") approve := r.FormValue("Approve") labnum, err := strconv.Atoi(r.FormValue("Labnum")) if err != nil { log.Println(err) http.Error(w, err.Error(), 404) return } if approve != "true" { log.Println("Missing approval") http.Error(w, "Not approved", 404) return } if !git.HasOrganization(course) || username == "" { log.Println("Missing username or uncorrect course") http.Error(w, "Unknown Organization", 404) return } org, err := git.NewOrganization(course, true) if err != nil { log.Println(err) http.Error(w, err.Error(), 404) return } if !org.IsTeacher(member) { log.Println(member.Name + " is not a teacher of " + org.Name) http.Error(w, "Not a teacher of this course.", 404) return } var isgroup bool if git.HasMember(username) { isgroup = false } else { isgroup = strings.Contains(username, "group") if !isgroup { log.Println("No user found") http.Error(w, "Unknown User", 404) return } } var latestbuild int var res *ci.BuildResult if isgroup { gnum, err := strconv.Atoi(username[len("group"):]) if err != nil { log.Println(err) http.Error(w, err.Error(), 404) return } group, err := git.NewGroup(course, gnum, false) if err != nil { log.Println(err) http.Error(w, err.Error(), 404) return } defer func() { if err := group.Save(); err != nil { group.Unlock() log.Println(err) } }() latestbuild = group.GetLastBuildID(labnum) if latestbuild < 0 { http.Error(w, "No build registered on lab.", 500) return } res, err = ci.GetBuildResult(latestbuild) if err != nil { log.Println(err) http.Error(w, err.Error(), 500) return } group.SetApprovedBuild(res.Labnum, res.ID, res.PushTime) if org.Slipdays { for username := range group.Members { user, err := git.NewMemberFromUsername(username, false) if err != nil { log.Println(err) continue } copt := user.Courses[org.Name] err = copt.RecalculateSlipDays() if err != nil { log.Println(err) } user.Courses[org.Name] = copt } } } else { user, err := git.NewMemberFromUsername(username, false) if err != nil { log.Println(err.Error()) http.Error(w, err.Error(), 500) return } defer func() { if err := user.Save(); err != nil { user.Unlock() log.Println(err) } }() latestbuild = user.GetLastBuildID(course, labnum) if latestbuild < 0 { http.Error(w, "No build registered on lab.", 500) return } res, err = ci.GetBuildResult(latestbuild) if err != nil { log.Println(err) http.Error(w, err.Error(), 500) return } user.SetApprovedBuild(org.Name, res.Labnum, res.ID, res.PushTime) if org.Slipdays { copt := user.Courses[org.Name] err = copt.RecalculateSlipDays() if err != nil { log.Println(err) } user.Courses[org.Name] = copt } } res.Status = "Approved" if err := res.Save(); err != nil { log.Println(err) http.Error(w, err.Error(), 500) return } }
// AddGroupMemberHandler is a http handler adding an additional member to a active group. func AddGroupMemberHandler(w http.ResponseWriter, r *http.Request) { view := AddGroupMemberView{} view.Error = true enc := json.NewEncoder(w) // Checks if the user is signed in and a teacher. member, err := checkTeacherApproval(w, r, true) if err != nil { err = enc.Encode(ErrSignIn) return } orgname := r.FormValue("course") if orgname == "" || !git.HasOrganization(orgname) { err = enc.Encode(ErrUnknownCourse) return } groupid, err := strconv.Atoi(r.FormValue("groupid")) if err != nil { view.ErrorMsg = err.Error() err = enc.Encode(view) return } if !git.HasGroup(groupid) { err = enc.Encode(ErrUnknownGroup) return } org, err := git.NewOrganization(orgname, false) if err != nil { view.ErrorMsg = err.Error() err = enc.Encode(view) return } defer func() { err := org.Save() if err != nil { org.Unlock() log.Println(err) } }() if !org.IsTeacher(member) { err = enc.Encode(ErrNotTeacher) return } group, err := git.NewGroup(orgname, groupid, false) if err != nil { view.ErrorMsg = err.Error() err = enc.Encode(view) return } defer func() { err := group.Save() if err != nil { group.Unlock() log.Println(err) } }() if group.TeamID == 0 { teams, err := org.ListTeams() if err != nil { view.ErrorMsg = err.Error() err = enc.Encode(view) return } if team, ok := teams[git.GroupRepoPrefix+strconv.Itoa(groupid)]; ok { group.TeamID = team.ID } else { view.ErrorMsg = "Error finding team on GitHub." err = enc.Encode(view) return } } r.ParseForm() members := r.PostForm["member"] for _, username := range members { if username == "" || !git.HasMember(username) { continue } group.AddMember(username) org.AddMemberToTeam(group.TeamID, username) delete(org.PendingRandomGroup, username) } group.Activate() view.Added = true view.Error = false enc.Encode(view) }
// ShowResultHandler is a http handler for showing a page detailing // lab resutls for a single user or group. func ShowResultHandler(w http.ResponseWriter, r *http.Request) { // Checks if the user is signed in and a teacher. member, err := checkTeacherApproval(w, r, true) if err != nil { return } // Gets the org and check if valid orgname := "" if path := strings.Split(r.URL.Path, "/"); len(path) == 4 { if !git.HasOrganization(path[3]) { http.Redirect(w, r, pages.HOMEPAGE, 307) return } orgname = path[3] } else { http.Redirect(w, r, pages.HOMEPAGE, 307) return } username := r.FormValue("user") if username == "" { http.Redirect(w, r, pages.HOMEPAGE, 307) return } if !git.HasOrganization(orgname) { http.Redirect(w, r, pages.HOMEPAGE, 307) return } org, err := git.NewOrganization(orgname, true) if err != nil { http.Error(w, err.Error(), 500) } isgroup := false groupid := -1 labnum := 0 if !git.HasMember(username) { groupnum, err := strconv.Atoi(username[len("group"):]) if err != nil { http.Redirect(w, r, pages.HOMEPAGE, 307) return } if git.HasGroup(groupnum) { isgroup = true group, err := git.NewGroup(org.Name, groupnum, true) if err != nil { http.Redirect(w, r, pages.HOMEPAGE, 307) return } groupid = group.ID if group.CurrentLabNum >= org.GroupAssignments { labnum = org.GroupAssignments } else { labnum = group.CurrentLabNum } } else { http.Redirect(w, r, pages.HOMEPAGE, 307) return } } else { user, err := git.NewMemberFromUsername(username, true) if err != nil { http.Error(w, err.Error(), 500) } nr := user.Courses[org.Name].CurrentLabNum if nr >= org.IndividualAssignments { labnum = org.IndividualAssignments } else { labnum = nr } } view := ShowResultView{ StdTemplate: StdTemplate{ Member: member, }, Org: org, Username: username, Labnum: labnum, IsGroup: isgroup, GroupID: groupid, } execTemplate("teacherresultpage.html", w, view) }
// StartTestBuildProcess will use the payload from github to start the ci build. func StartTestBuildProcess(load github.PushPayload) (err error) { userlogin := *load.Pusher.Name reponame := *load.Repo.Name orgname := *load.Organization.Login if !git.HasMember(userlogin) { log.Println("Not a valid user: "******"Not a valid org: ", orgname) return errors.New("Not a valid org: " + orgname) } org, err := git.NewOrganization(orgname, true) user, err := git.NewMemberFromUsername(userlogin, true) isgroup := !strings.Contains(reponame, "-"+git.StandardRepoName) var labfolder string var destfolder string var labnum int var username string var gnum = -1 if isgroup { gnum, err = strconv.Atoi(reponame[len("group"):]) if err != nil { log.Println(err) return err } group, err := git.NewGroup(org.Name, gnum, true) if err != nil { log.Println(err) return err } labnum = group.CurrentLabNum if labnum > org.GroupAssignments { labnum = org.GroupAssignments } labfolder = org.GroupLabFolders[labnum] username = reponame destfolder = git.GroupsRepoName } else { labnum = user.Courses[org.Name].CurrentLabNum if labnum > org.IndividualAssignments { labnum = org.IndividualAssignments } labfolder = org.IndividualLabFolders[labnum] username = strings.TrimRight(reponame, "-"+git.StandardRepoName) destfolder = git.StandardRepoName } opt := ci.DaemonOptions{ Org: org.Name, User: username, Group: gnum, Repo: reponame, BaseFolder: org.CI.Basepath, LabFolder: labfolder, LabNumber: labnum, AdminToken: org.AdminToken, DestFolder: destfolder, IsPush: true, Secret: org.CI.Secret, } go ci.StartTesterDaemon(opt) return }