public ActionResult Edit(ContestDetailModel model) { if (model == null) { throw new ArgumentNullException(nameof(model)); } // 验证数据模型。 if (!ValidateContestDetailModel(model)) { return(View(model)); } // 执行用户身份验证。 ContestHandle handle = new ContestHandle(model.ContestId); using (ContestDataProvider data = ContestDataProvider.Create(handle, true)) { if (!UserSession.IsAuthorized(Session) || string.Compare(data.Creator, UserSession.GetUsername(Session), false) != 0) { return(Redirect("~/Error/AccessDenied")); } } model.SaveTo(handle); return(Redirect($"~/Contest/Show?id={model.ContestId}")); }
public ActionResult AddProblem(ProblemDetailModel model) { // 检查参数。 if (string.IsNullOrEmpty(Request.QueryString["id"])) { return(Redirect("~/Contest")); } int contestId; if (!int.TryParse(Request.QueryString["id"], out contestId)) { return(Redirect("~/Contest")); } if (!ContestManager.Default.IsContestExist(contestId)) { return(Redirect("~/Contest")); } // 验证数据模型。 if (!TryValidateModel(model)) { ViewBag.TitleErrorMessage = ModelStateHelper.GetFirstError(ModelState, "Title"); return(View(model)); } ContestHandle contestHandle = new ContestHandle(contestId); using (ContestDataProvider contestData = ContestDataProvider.Create(contestHandle, false)) { // 验证用户操作权限。 if (!UserSession.IsAuthorized(Session) || string.Compare(contestData.Creator, UserSession.GetUsername(Session), false) != 0) { return(Redirect("~/Error/AccessDenied")); } // 在题目库中创建题目。 ProblemHandle problemHandle = ProblemArchieveManager.Default.CreateProblem( contestData.PeekNextProblemId()); model.ResetNullStrings(); model.SaveTo(problemHandle); // 为避免死锁,该句不应放置在下面的 using 块中。 using (ProblemDataProvider problemData = ProblemDataProvider.Create(problemHandle, false)) { problemData.ContestId = contestId; problemData.AuthorizationGroup = UserGroup.Guests; } // 将创建的题目添加至当前比赛中。 contestData.AddProblem(problemHandle); } return(Redirect($"~/Contest/Show?id={contestId}")); }
// GET: Archieve/TestSet?id={ProblemID} public ActionResult TestSet() { // 执行用户身份验证。 if (!UserSession.IsAuthorized(Session)) { return(Redirect("~/Error/AccessDenied")); } // 检查查询参数。 if (string.IsNullOrEmpty(Request.QueryString["id"])) { return(Redirect("~/Archieve")); } string problemId = Request.QueryString["id"]; ProblemHandle problemHandle = ProblemArchieveManager.Default.GetProblemById(problemId); if (problemHandle == null) { // 给定的题目不存在。 return(Redirect("~/Archieve")); } using (ProblemDataProvider problemData = ProblemDataProvider.Create(problemHandle, true)) { // 执行进一步身份验证。 if (problemData.ContestId == -1) { if (!UserAuthorization.CheckAccessRights(UserGroup.Administrators, UserSession.GetUserGroup(Session))) { return(Redirect("~/Error/AccessDenied")); } } else { ContestHandle contestHandle = new ContestHandle(problemData.ContestId); using (ContestDataProvider contestData = ContestDataProvider.Create(contestHandle, true)) { if (string.Compare(contestData.Creator, UserSession.GetUsername(Session), false) != 0) { return(Redirect("~/Error/AccessDenied")); } } } } // TODO: 完成 Archieve/TestSet 控制器逻辑。 return(View()); }
/// <summary> /// 获取给定用户对给定比赛的数据操作权限。 /// </summary> /// <param name="contest">比赛句柄。</param> /// <param name="user">用户句柄。若当前活动会话中不存在活动的登录用户,传入 null。</param> /// <returns>一个 DataAccess 枚举,表示给定用户对于给定比赛的数据操作权限。</returns> /// <exception cref="ArgumentNullException"/> public static DataAccess GetUserAccess(ContestHandle contest, UserHandle user) { if (contest == null) { throw new ArgumentNullException(nameof(contest)); } /* * 检查顺序如下: * 1. 当前活动会话中无活动登录用户。 * 2. 用户为管理员身份; * 3. 用户为比赛创建者; * 4. 用户为比赛注册用户。 * */ if (user == null) { return(DataAccess.None); } // 检查用户是否为管理员身份。 if (UserAuthorization.CheckAccessRights(UserGroup.Administrators, UserAuthorization.GetUserGroup(user))) { return(DataAccess.ReadWrite); } // 检查用户是否为比赛创建者。 using (ContestDataProvider contestData = ContestDataProvider.Create(contest, true)) { if (string.Compare(contestData.Creator, user.Username, false) == 0) { return(DataAccess.ReadWrite); } } // 检查用户是否已经注册。 if (GetUserAuthorizationState(contest, user).RegisterState == ContestRegisterState.NotRegistered) { // 未注册用户。不具备数据访问及操作权限。 return(DataAccess.None); } else { // 注册用户。具有读权限。 return(DataAccess.Read); } }
/// <summary> /// 将给定的队伍添加至给定的比赛的注册队伍列表中。 /// </summary> /// <param name="contest">比赛句柄。</param> /// <param name="team">要添加的队伍句柄。</param> /// <exception cref="ArgumentNullException"/> public static void Register(ContestHandle contest, TeamHandle team) { if (contest == null) { throw new ArgumentNullException(nameof(contest)); } if (team == null) { throw new ArgumentNullException(nameof(team)); } using (ContestDataProvider contestData = ContestDataProvider.Create(contest, false)) { contestData.AddTeamToAuthorizedList(team); } }
/// <summary> /// 将给定的用户添加至给定的比赛的注册用户列表中。 /// </summary> /// <param name="contest">比赛句柄。</param> /// <param name="user">要添加的用户句柄。</param> /// <exception cref="ArgumentNullException"/> public static void Register(ContestHandle contest, UserHandle user) { if (contest == null) { throw new ArgumentNullException(nameof(contest)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } using (ContestDataProvider contestData = ContestDataProvider.Create(contest, false)) { contestData.AddUserToAuthorizedList(user); } }
public ActionResult AddArchieveProblem(FormCollection form) { // 验证参数。 if (string.IsNullOrEmpty(Request.QueryString["contestId"]) || string.IsNullOrEmpty(form["ProblemId"])) { return(new ContentResult()); } string problemId = form["ProblemId"]; int contestId; if (!int.TryParse(Request.QueryString["contestId"], out contestId)) { return(new ContentResult()); } if (!ProblemArchieveManager.Default.IsProblemExist(problemId) || !ContestManager.Default.IsContestExist(contestId)) { return(new ContentResult()); } using (ContestDataProvider contestData = ContestDataProvider.Create(new ContestHandle(contestId), false)) { // 检查用户操作权限。 if (!UserSession.IsAuthorized(Session) || string.Compare(contestData.Creator, UserSession.GetUsername(Session), false) != 0) { return(new ContentResult()); } // 执行操作。 // 创建源题目的精确副本到当前比赛中。 ProblemHandle newProblemHandle = ProblemArchieveManager.Default.CloneProblem( contestData.PeekNextProblemId(), problemId); using (ProblemDataProvider problemData = ProblemDataProvider.Create(newProblemHandle, false)) { problemData.ContestId = contestId; } contestData.AddProblem(newProblemHandle); } return(new ContentResult()); }
// GET: /Status/ShowSubmission?id={SubmissionID} public ActionResult ShowSubmission() { // 检查查询参数。 if (string.IsNullOrEmpty(Request.QueryString["id"])) { return(Redirect("~/Status")); } int submissionId; if (!int.TryParse(Request.QueryString["id"], out submissionId)) { return(Redirect("~/Status")); } SubmissionHandle submissionHandle = SubmissionManager.Default.QuerySubmissionById(submissionId); if (submissionHandle == null) { // 给定的用户提交不存在。 return(Redirect("~/Status")); } // 验证操作权限。 using (SubmissionDataProvider submissionData = SubmissionDataProvider.Create(submissionHandle, true)) { if (submissionData.ContestId != -1) { ContestHandle contestHandle = new ContestHandle(submissionData.ContestId); using (ContestDataProvider contestData = ContestDataProvider.Create(contestHandle, true)) { if (contestData.Status != ContestStatus.Ended && string.Compare(submissionData.Username, UserSession.GetUsername(Session)) != 0) { return(Redirect(Request.UrlReferrer.ToString())); } } } } SubmissionDetailModel model = SubmissionDetailModel.FromSubmissionHandle(submissionHandle); return(View(model)); }
/// <summary> /// 检查给定的密码是否与给定比赛的密码匹配。 /// </summary> /// <param name="contest">比赛句柄。</param> /// <param name="password">密码。</param> /// <returns>一个值,该值指示给定的密码是否与给定比赛的密码匹配。</returns> /// <exception cref="ArgumentNullException"/> public static bool CheckContestPassword(ContestHandle contest, string password) { if (contest == null) { throw new ArgumentNullException(nameof(contest)); } if (password == null) { throw new ArgumentNullException(nameof(password)); } byte[] hash = PasswordHashAlgorithm.ComputeHash(PasswordEncoding.GetBytes(password)); // 比较密码哈希值是否相同。 using (ContestDataProvider contestData = ContestDataProvider.Create(contest, true)) { return(Buffer.IsByteArraysEqual(hash, contestData.PasswordHash)); } }
/// <summary> /// 更新比赛密码。 /// </summary> /// <param name="contest">比赛句柄。</param> /// <param name="password">更新后的密码。</param> /// <exception cref="ArgumentNullException"/> public static void UpdateContestPassword(ContestHandle contest, string password) { if (contest == null) { throw new ArgumentNullException(nameof(contest)); } if (password == null) { throw new ArgumentNullException(nameof(password)); } // 计算密码哈希值。 byte[] hash = PasswordHashAlgorithm.ComputeHash(PasswordEncoding.GetBytes(password)); using (ContestDataProvider contestData = ContestDataProvider.Create(contest, false)) { contestData.PasswordHash = hash; } }
public ActionResult ContestDetail() { string contestIdString = Request.QueryString["id"]; if (string.IsNullOrEmpty(contestIdString)) { return(QueryResult(1, "Contest ID required.")); } int contestId; if (!int.TryParse(contestIdString, out contestId)) { return(QueryResult(2, "Invalid contest ID.")); } // 检查用户权限。 ContestHandle contest = new ContestHandle(contestId); DataAccess access = ContestAuthorization.GetUserAccess(contest, UserSession.GetUserHandle(Session)); if (access == DataAccess.None) { return(QueryResult(3, "Access denied.")); } else if (access == DataAccess.Read) { // 用户对于该场比赛处于只读状态。检查比赛的执行状态。 bool loadProblems = true; using (ContestDataProvider contestData = ContestDataProvider.Create(contest, true)) { if (contestData.Status == ContestStatus.Pending) { loadProblems = false; } } return(QueryResult(ContestDisplayModel.FromContestHandle(contest, loadProblems))); } else { return(QueryResult(ContestDisplayModel.FromContestHandle(contest, true))); } }
/// <summary> /// 将当前数据模型中的内容保存至给定的比赛。 /// </summary> /// <param name="handle">比赛句柄。</param> /// <exception cref="ArgumentNullException"/> public void SaveTo(ContestHandle handle) { if (handle == null) { throw new ArgumentNullException(nameof(handle)); } using (ContestDataProvider data = ContestDataProvider.Create(handle, false)) { data.Title = Title; data.Creator = Creator; data.AuthorizationGroup = UsergroupConvert.ConvertFromString(UsergroupName); data.StartTime = DateTime.ParseExact(StartTimeString, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US")); data.EndTime = DateTime.ParseExact(EndTimeString, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US")); data.ParticipationMode = ContestParticipationModeConvert.ConvertFromString(ParticipationModeName); data.AuthorizationMode = ContestAuthorizationModeConvert.ConvertFromString(AuthorizationModeName); } ContestAuthorization.UpdateContestPassword(handle, Password ?? string.Empty); }
public ActionResult SetAnnouncement(FormCollection form) { string contestIdString = Request.QueryString["id"]; if (string.IsNullOrEmpty(contestIdString)) { return(new ContentResult()); } int contestId; if (!int.TryParse(contestIdString, out contestId)) { return(new ContentResult()); } string announcement = form["announcementContent"]; if (string.IsNullOrEmpty(announcement)) { return(new ContentResult()); } // 检查用户身份权限。 ContestHandle contest = new ContestHandle(contestId); UserHandle user = UserSession.GetUserHandle(Session); if (!ContestAuthorization.GetUserAccess(contest, user).HasFlag(DataAccess.Write)) { // 用户对当前的比赛没有写权限。 return(new ContentResult()); } using (ContestDataProvider contestData = ContestDataProvider.Create(contest, false)) { contestData.Announcement = announcement; } return(new ContentResult()); }
/// <summary> /// 从给定的比赛句柄创建 ContestDisplayMode 类的新实例。 /// </summary> /// <param name="handle">比赛句柄。</param> /// <param name="loadProblems">一个值,该值指示是否加载题目列表。</param> /// <returns>从给定比赛创建的 ContestDisplayModel 对象。</returns> /// <exception cref="ArgumentNullException"/> public static ContestDisplayModel FromContestHandle(ContestHandle handle, bool loadProblems) { if (handle == null) { throw new ArgumentNullException(nameof(handle)); } ContestDisplayModel model = new ContestDisplayModel(); using (ContestDataProvider data = ContestDataProvider.Create(handle, true)) { model.ContestId = data.ContestId; model.Title = data.Title; model.Creator = data.Creator; model.Announcement = new Markdown().Transform(data.Announcement); model.StartTime = data.StartTime; model.EndTime = data.EndTime; model.Status = data.Status; model.AuthorizationMode = data.AuthorizationMode; model.ParticipationMode = data.ParticipationMode; if (loadProblems) { ProblemHandle[] handles = data.GetProblems(); model.Problems = new ProblemBriefModel[handles.Length]; for (int i = 0; i < handles.Length; ++i) { model.Problems[i] = ProblemBriefModel.FromProblemHandle(handles[i]); } } else { model.Problems = new ProblemBriefModel[0]; } } return(model); }
/// <summary> /// 从给定的比赛句柄创建 ContestBriefModel 类的新实例。 /// </summary> /// <param name="handle">比赛句柄。</param> /// <returns>从给定的比赛句柄创建的 ContestBriefModel 类对象。</returns> /// <exception cref="ArgumentNullException"/> public static ContestBriefModel FromContestHandle(ContestHandle handle) { if (handle == null) { throw new ArgumentNullException(nameof(handle)); } ContestBriefModel model = new ContestBriefModel(); using (ContestDataProvider data = ContestDataProvider.Create(handle, true)) { model.ContestId = data.ContestId; model.Title = data.Title; model.Creator = data.Creator; model.StartTime = data.StartTime; model.EndTime = data.EndTime; model.AuthorizationMode = data.AuthorizationMode; model.ParticipationMode = data.ParticipationMode; model.Status = data.Status; } return(model); }
public ActionResult Edit() { // 检查查询参数。 if (string.IsNullOrEmpty(Request.QueryString["id"])) { return(Redirect("~/Contest")); } int contestId; if (!int.TryParse(Request.QueryString["id"], out contestId)) { return(Redirect("~/Contest")); } if (!ContestManager.Default.IsContestExist(contestId)) { return(Redirect("~/Contest")); } ContestHandle contest = new ContestHandle(contestId); using (ContestDataProvider data = ContestDataProvider.Create(contest, false)) { // 验证用户身份权限。 if (!UserSession.IsAuthorized(Session) || string.Compare(data.Creator, UserSession.GetUsername(Session), false) != 0) { return(Redirect("~/Error/AccessDenied")); } } ContestDetailModel model = ContestDetailModel.FromContestHandle(contest); return(View(model)); }
/// <summary> /// 从给定的比赛句柄创建 ContestDetailModel 类的新实例。 /// </summary> /// <param name="handle">比赛句柄。</param> /// <returns>从给定的比赛句柄创建的比赛详细信息数据模型对象。</returns> /// <exception cref="ArgumentNullException"/> public static ContestDetailModel FromContestHandle(ContestHandle handle) { if (handle == null) { throw new ArgumentNullException(nameof(handle)); } ContestDetailModel model = new ContestDetailModel(); using (ContestDataProvider data = ContestDataProvider.Create(handle, true)) { model.ContestId = data.ContestId; model.Title = data.Title; model.Creator = data.Creator; model.UsergroupName = UsergroupConvert.ConvertToString(data.AuthorizationGroup); model.CreationTime = data.CreationTime; model.StartTimeString = data.StartTime.ToString("yyyy-MM-dd HH:mm:ss"); model.EndTimeString = data.EndTime.ToString("yyyy-MM-dd HH:mm:ss"); model.AuthorizationModeName = ContestAuthorizationModeConvert.ConvertToString(data.AuthorizationMode); model.ParticipationModeName = ContestParticipationModeConvert.ConvertToString(data.ParticipationMode); } return(model); }
/// <summary> /// 获取给定的用户在给定的比赛中的注册信息。 /// </summary> /// <param name="contest">比赛句柄。</param> /// <param name="user">用户句柄。若当前登录会话中不存在活动用户,传入 null。</param> /// <returns>一个 ContestAuthorizationState 类实例对象,其中封装了给定的用户在给定的比赛中的注册信息。</returns> /// <exception cref="ArgumentNullException"/> public static ContestAuthorizationState GetUserAuthorizationState(ContestHandle contest, UserHandle user) { if (contest == null) { throw new ArgumentNullException(nameof(contest)); } /* * 检查顺序如下: * 1. 当前会话中有活动的登录用户; * 2. 用户以个人名义注册了比赛; * 3. 用户以队伍名义注册了比赛; * 4. 用户为比赛创建者; * 5. 用户用户组权限低于比赛的最低访问用户组权限; * 5. 比赛为开放比赛; * 6. 比赛为密码保护比赛。 * */ // 检查当前会话中是否存在活动的登录用户。 if (user == null) { return(new ContestAuthorizationState(ContestRegisterState.NotRegistered)); } using (ContestDataProvider contestData = ContestDataProvider.Create(contest, true)) { // 检查用户是否以个人名义参加比赛。 if (contestData.ParticipationMode == ContestParticipationMode.IndividualOnly || contestData.ParticipationMode == ContestParticipationMode.Both) { foreach (UserHandle registeredUser in contestData.GetAuthorizedUsers()) { if (registeredUser == user) { return(new ContestAuthorizationState(ContestRegisterState.IndividualRegistered)); } } } // 检查用户所在的队伍是否参加比赛。 if (contestData.ParticipationMode == ContestParticipationMode.TeamworkOnly || contestData.ParticipationMode == ContestParticipationMode.Both) { foreach (TeamHandle registeredTeam in contestData.GetAuthorizedTeams()) { if (registeredTeam.IsUserIn(user)) { return(new ContestAuthorizationState(ContestRegisterState.TeamRegistered) { TeamId = registeredTeam.TeamId }); } } } // 检查用户是否为比赛创建者。 if (string.Compare(contestData.Creator, user.Username, false) == 0) { return(new ContestAuthorizationState(ContestRegisterState.IndividualRegistered)); } // 检查用户权限。 if (!UserAuthorization.CheckAccessRights(contestData.AuthorizationGroup, UserAuthorization.GetUserGroup(user))) { return(new ContestAuthorizationState(ContestRegisterState.NotRegistered)); } else if (UserAuthorization.CheckAccessRights(UserGroup.Administrators, UserAuthorization.GetUserGroup(user))) { return(new ContestAuthorizationState(ContestRegisterState.IndividualRegistered)); } // 检查比赛是否为开放或者密码保护比赛。 if (contestData.AuthorizationMode == ContestAuthorizationMode.Public) { return(new ContestAuthorizationState(ContestRegisterState.IndividualRegistered)); } else if (contestData.AuthorizationMode == ContestAuthorizationMode.Protected) { return(new ContestAuthorizationState(ContestRegisterState.PasswordRequired)); } } // 所有检查均不成立。 return(new ContestAuthorizationState(ContestRegisterState.NotRegistered)); }