/// <summary> /// Gets a specific event by ID. /// </summary> /// <returns></returns> public ActionResult GetEvent() { GetEventRequest request = ApiRequestBase.ParseRequest <GetEventRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } Event ev = null; using (DB db = new DB(p.Name)) { ev = db.GetEvent(request.eventId); if (ev != null) { db.AddReadState(session.GetUser().UserId, ev.EventId); } } if (ev != null) { GetEventDataResponse response = new GetEventDataResponse(); response.ev = ev; response.eventListCustomTagKey = session.GetUser().GetEventListCustomTagKey(p.Name); return(Json(response)); } return(ApiError("Unable to find event with ID " + request.eventId)); }
public ActionResult AddFilter() { AddFilterRequest request = ApiRequestBase.ParseRequest <AddFilterRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { Filter newFilter = new Filter(); newFilter.Name = request.name; if (Enum.IsDefined(typeof(ConditionHandling), request.conditionHandling)) { newFilter.ConditionHandling = request.conditionHandling; } if (db.AddFilter(newFilter, request.conditions, out string errorMessage)) { Logger.Info("[" + p.Name + "] Filter " + newFilter.FilterId + " (\"" + newFilter.Name + "\") was added by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); } else { return(ApiError(errorMessage)); } } }
/// <summary> /// Gets all login records within a time range, ordered by Date descending. Session must have admin privilege. /// </summary> /// <returns></returns> public ActionResult GeolocateIP() { GeolocateIPRequest request = ApiRequestBase.ParseRequest <GeolocateIPRequest>(this); if (IPAddress.TryParse(request.ip, out IPAddress ip)) { string url = Settings.data.geolocationWebServiceBaseUrl; if (string.IsNullOrWhiteSpace(url)) { return(ApiError("The geolocation web service endpoint is not configured.")); } if (!url.EndsWith("/")) { url += "/"; } url += "embed/" + ip.ToString(); BpWebResponse proxyResponse = proxyClient.GET(url); return(Json(new GeolocateIPResponse() { html = proxyResponse.str })); } else { return(ApiError("Invalid IP Address")); } }
public ActionResult FinishChange() { ChangePasswordRequest request = ApiRequestBase.ParseRequest <ChangePasswordRequest>(this); byte[] challenge = session.authChallenge; if (challenge == null || challenge.Length == 0) { return(ApiError("Missing session state. Please retry.")); } User user = session.GetUser(); if (user.AuthenticateUser(request.oldPwToken, challenge)) { byte[] newPwTokenBytes = Hex.ToByteArray(request.newPwToken); byte[] encryptionKey = Hash.GetSHA512Bytes(user.PasswordHash, challenge); byte[] decryptedNewPwHash = ByteUtil.XORByteArrays(encryptionKey, newPwTokenBytes); user.PasswordHash = Hash.GetSHA512Bytes(decryptedNewPwHash); Settings.data.Save(); session.authChallenge = null; return(Json(new ApiResponseBase(true))); } else { return(ApiError("Old password was incorrect.")); } }
public ActionResult AddProject() { ProjectRequest request = ApiRequestBase.ParseRequest <ProjectRequest>(this); if (string.IsNullOrWhiteSpace(request.projectName) || !StringUtil.IsAlphaNumericOrUnderscore(request.projectName)) { return(Json(new ApiResponseBase(false, "project name is invalid"))); } request.projectName = request.projectName.Trim(); if (request.projectName.Length > 64) { return(Json(new ApiResponseBase(false, "project name is too long. Max length: 64 characters."))); } Project p = new Project(); p.Name = request.projectName; p.InitializeSubmitKey(); if (Settings.data.TryAddProject(p)) { Settings.data.Save(); Logger.Info("Project \"" + request.projectName + "\" was added by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); } else { return(Json(new ApiResponseBase(false, "project name is already taken"))); } }
public ActionResult Logout() { ApiRequestBase args = ApiRequestBase.ParseRequest <ApiRequestBase>(this); SessionManager.RemoveSession(args.sid); return(Json(new ApiResponseBase(true))); }
public ActionResult SetSettingsData() { SetSettingsRequest request = ApiRequestBase.ParseRequest <SetSettingsRequest>(this); bool requiresRestart = false; Settings.data.systemName = request.settings.systemName; if (Settings.data.port_http != request.settings.port_http) { Settings.data.port_http = request.settings.port_http; requiresRestart = true; } if (Settings.data.port_https != request.settings.port_https) { Settings.data.port_https = request.settings.port_https; requiresRestart = true; } Settings.data.appPath = request.settings.appPath; if (Settings.data.certificatePath != request.settings.certificatePath) { Settings.data.certificatePath = request.settings.certificatePath; requiresRestart = true; } if (Settings.data.certificatePassword != request.settings.certificatePassword) { Settings.data.certificatePassword = request.settings.certificatePassword; requiresRestart = true; } Settings.data.loginStyle = request.settings.loginStyle.ToString(); Settings.data.geolocationWebServiceBaseUrl = request.settings.geolocationWebServiceBaseUrl.ToString(); Settings.data.trustedProxyIPs = request.settings.trustedProxyIPs; Settings.data.useXRealIP = request.settings.useXRealIP; Settings.data.useXForwardedFor = request.settings.useXForwardedFor; Settings.data.smtpHost = request.settings.smtpHost; Settings.data.smtpPort = request.settings.smtpPort; Settings.data.smtpSsl = request.settings.smtpSsl; Settings.data.smtpUser = request.settings.smtpUser; Settings.data.smtpPass = request.settings.smtpPass; Settings.data.smtpSendFrom = request.settings.smtpSendFrom; Settings.data.defaultErrorEmail = request.settings.defaultErrorEmail; Settings.data.verboseSubmitLogging = request.settings.verboseSubmitLogging; Settings.data.serviceWorkerEnabled = request.settings.serviceWorkerEnabled; Settings.data.Save(); SetSettingsResponse response = new SetSettingsResponse(true, null); if (requiresRestart) { response.message = "Some changes will take effect the next time the web server is restarted."; } return(Json(response)); }
public ActionResult RunEnabledFiltersAgainstAllEvents() { ProjectRequestBase request = ApiRequestBase.ParseRequest <ProjectRequestBase>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (FilterEngine fe = new FilterEngine(request.projectName)) fe.RunEnabledFiltersAgainstAllEvents(); return(Json(new ApiResponseBase(true))); }
public ActionResult RunFilterAgainstAllEvents() { OneFilterRequest request = ApiRequestBase.ParseRequest <OneFilterRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (FilterEngine fe = new FilterEngine(request.projectName)) fe.RunFilterAgainstAllEvents(request.filterId, true); return(Json(new ApiResponseBase(true))); }
/// <summary> /// Sets the custom tag to be included in event summaries provided to this user. Set null to unset the preference. /// </summary> /// <returns></returns> public ActionResult SetEventListCustomTagKey() { SetEventListCustomTagKeyRequest request = ApiRequestBase.ParseRequest <SetEventListCustomTagKeyRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } session.GetUser().SetEventListCustomTagKey(p.Name, request.eventListCustomTagKey); Settings.data.Save(); return(Json(new ApiResponseBase(true))); }
public ActionResult GetAllFilters() { ProjectRequestBase request = ApiRequestBase.ParseRequest <ProjectRequestBase>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } GetAllFiltersResponse response = new GetAllFiltersResponse(); using (DB db = new DB(p.Name)) response.filters = db.GetAllFiltersSummary(); return(Json(response)); }
/// <summary> /// Gets all login records for the specified user, ordered by Date descending. Session must have admin privilege. /// </summary> /// <returns></returns> public ActionResult GetLoginRecordsForUser() { if (!session.IsAdminValid) { return(ApiError("Not Authorized")); } LoginRecordsByUserNameRequest request = ApiRequestBase.ParseRequest <LoginRecordsByUserNameRequest>(this); using (GlobalDb db = new GlobalDb()) return(Json(new LoginRecordsResponse() { records = db.GetLoginRecordsByUserName(request.userName) })); }
public ActionResult AddFolder() { AddFolderRequest request = ApiRequestBase.ParseRequest <AddFolderRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { if (db.AddFolder(request.folderName, request.parentFolderId, out string errorMessage, out Folder newFolder)) { return(Json(new ApiResponseBase(true))); }
/// <summary> /// Gets all login records within a time range, ordered by Date descending. Session must have admin privilege. /// </summary> /// <returns></returns> public ActionResult GetLoginRecordsGlobal() { if (!session.IsAdminValid) { return(ApiError("Not Authorized")); } LoginRecordsGlobalRequest request = ApiRequestBase.ParseRequest <LoginRecordsGlobalRequest>(this); using (GlobalDb db = new GlobalDb()) return(Json(new LoginRecordsResponse() { records = db.GetLoginRecordsGlobal(request.startDate, request.endDate) })); }
public ActionResult GetFilter() { OneFilterRequest request = ApiRequestBase.ParseRequest <OneFilterRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } GetFilterResponse response = new GetFilterResponse(); using (DB db = new DB(p.Name)) response.filter = db.GetFilter(request.filterId); return(Json(response)); }
public ActionResult GetFolderStructure() { ProjectRequestBase request = ApiRequestBase.ParseRequest <ProjectRequestBase>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } GetFolderStructureResponse response = new GetFolderStructureResponse(); using (DB db = new DB(p.Name)) response.root = db.GetFolderStructure(); return(Json(response)); }
/// <summary> /// Gets the number of unread events in every folder that contains unread events. /// </summary> /// <returns></returns> public ActionResult CountUnreadEventsByFolder() { ProjectRequestBase request = ApiRequestBase.ParseRequest <ProjectRequestBase>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { Dictionary <int, uint> folderIdToUnreadEventCount = db.CountUnreadEventsByFolder(session.GetUser().UserId); return(Json(new CountUnreadEventsByFolderResponse(folderIdToUnreadEventCount))); } }
public ActionResult GetRegistrationStatus() { PushRegistrationRequest request = ApiRequestBase.ParseRequest <PushRegistrationRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } User user = session.GetUser(); string[] keys = user.GetPushNotificationSubscriptions(request.projectName, request.folderId); bool subscribed = keys.Contains(request.subscriptionKey); return(Json(new GetRegistrationStatusResponse(subscribed))); }
public ActionResult UnregisterForPush() { PushRegistrationRequest request = ApiRequestBase.ParseRequest <PushRegistrationRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } User user = session.GetUser(); user.SetPushNotificationSubscription(request.projectName, request.folderId, request.subscriptionKey, false); Settings.data.Save(); return(Json(new ApiResponseBase(true))); }
public ActionResult ReorderFilters() { ReorderFiltersRequest request = ApiRequestBase.ParseRequest <ReorderFiltersRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { db.ReorderFilters(request.newOrder); } Logger.Info("[" + p.Name + "] Filters reordered by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); }
public ActionResult ReplaceSubmitKey() { ProjectRequest request = ApiRequestBase.ParseRequest <ProjectRequest>(this); Project p = Settings.data.GetProject(request.projectName); if (p == null) { return(Json(new ApiResponseBase(false, "project could not be found"))); } p.InitializeSubmitKey(); Settings.data.Save(); Logger.Info("Project \"" + request.projectName + "\" had its submit key replaced by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); }
/// <summary> /// Sets the color of events by ID. /// </summary> /// <returns></returns> public ActionResult SetEventsColor() { SetEventsColorRequest request = ApiRequestBase.ParseRequest <SetEventsColorRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { if (db.SetEventsColor(request.eventIds, request.color)) { return(Json(new ApiResponseBase(true))); } return(ApiError("Unable to delete all events with IDs " + string.Join(",", request.eventIds))); } }
/// <summary> /// Move events by ID to a new folder by ID. /// </summary> /// <returns></returns> public ActionResult MoveEvents() { MoveEventsRequest request = ApiRequestBase.ParseRequest <MoveEventsRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { if (db.MoveEvents(request.eventIds, request.newFolderId)) { return(Json(new ApiResponseBase(true))); } return(ApiError("Unable to move all events with IDs " + string.Join(",", request.eventIds))); } }
/// <summary> /// May allow or disallow access to the controller. This is called before the client-specified action method is called. /// </summary> /// <param name="result">If authorization fails, this should be set to an appropriate result such as an HTTP 403 Forbidden response. If null, authorization will be assumed to have succeeded.</param> public override void OnAuthorization(ref ActionResult result) { base.OnAuthorization(ref result); if (result != null) { return; } ApiRequestBase args = ApiRequestBase.ParseRequest <ApiRequestBase>(this); session = args.GetSession(); if (session == null) { result = StatusCode("403 Forbidden"); } else if (!session.IsAuthValid) { result = StatusCode("418 Insufficient Privilege"); } }
public ActionResult InitiateRequest() { if (!Emailer.Enabled) { return(ApiError("This server does not have email configured. Therefore, this function is not usable.")); } if (requestLimiterByIP.Get(Context.httpProcessor.RemoteIPAddressStr)) { return(ApiError("A password reset request was recently initiated from " + Context.httpProcessor.RemoteIPAddressStr + ". Rate-limiting is in effect. Please wait " + TimeSpan.FromMinutes(minutesBetweenRequestsByIp).TotalSeconds + " seconds between requests.")); } requestLimiterByIP.Add(Context.httpProcessor.RemoteIPAddressStr, true); ForgotPasswordRequest request = ApiRequestBase.ParseRequest <ForgotPasswordRequest>(this); ErrorTrackerPasswordReset resetter = new ErrorTrackerPasswordReset(); PasswordResetRequest req = resetter.GetResetRequest(request.accountIdentifier); if (req != null) { if (requestLimiterByUsername.Get(req.accountIdentifier)) { return(ApiError("A password reset request was recently received for this user. Rate-limiting is in effect. Please wait " + TimeSpan.FromMinutes(minutesBetweenRequestsByName).TotalMinutes + " minutes between requests.")); } requestLimiterByUsername.Add(req.accountIdentifier, true); StringBuilder sb = new StringBuilder(); sb.Append("Hello "); sb.Append(req.displayName); sb.Append(",\r\n\r\n"); sb.Append("Someone at the address \"" + Context.httpProcessor.RemoteIPAddressStr + "\" has requested a reset of your password at \"" + Settings.data.systemName + "\". If you did not make this request, you can ignore this message and your password will not be changed.\r\n\r\n"); sb.Append("Here is your Security Code:\r\n\r\n"); sb.Append("-----------------------------\r\n"); sb.Append(req.secureToken); sb.Append("\r\n-----------------------------"); sb.Append("\r\n\r\nCopy it to the \"Password Recovery\" page and a new password will be emailed to you. This code expires in "); sb.Append((int)req.tokenExpiration.TotalMinutes); sb.Append(" minutes.\r\n\r\n(This email is automated. Please do not reply.)"); Emailer.SendEmail(req.email, Settings.data.systemName + " Password Recovery", sb.ToString(), false); } return(Json(new ApiResponseBase(true))); }
public ActionResult SearchAdvanced() { SearchAdvancedRequest request = ApiRequestBase.ParseRequest <SearchAdvancedRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } SearchResultsResponse response = new SearchResultsResponse(); using (FilterEngine fe = new FilterEngine(p.Name)) { HashSet <long> readEventIds = new HashSet <long>(fe.db.GetAllReadEventIds(session.GetUser().UserId)); response.events = fe.AdvancedSearch(request.conditions, request.matchAll, request.folderId, session.GetUser().GetEventListCustomTagKey(p.Name)) .Select(ev => ProduceEventSummary(ev, readEventIds)) .ToList(); } return(Json(response)); }
public ActionResult RemoveProject() { ProjectRequest request = ApiRequestBase.ParseRequest <ProjectRequest>(this); Project p = Settings.data.GetProject(request.projectName); if (p == null) { return(Json(new ApiResponseBase(false, "project could not be found"))); } if (Settings.data.TryRemoveProject(request.projectName) != null) { Settings.data.Save(); Logger.Info("Project \"" + request.projectName + "\" was deleted by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); } else { return(Json(new ApiResponseBase(false, "project could not be found"))); } }
public ActionResult AddCondition() { OneFilterConditionRequest request = ApiRequestBase.ParseRequest <OneFilterConditionRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { if (db.AddFilterCondition(request.condition, out string errorMessage)) { Logger.Info("[" + p.Name + "] Filter condition " + request.condition.FilterConditionId + " was added by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); } else { return(ApiError(errorMessage)); } } }
/// <summary> /// Updates a filter and all attached conditions and actions. This method cannot be used to add or remove conditions or actions, or to update filter properties separately from conditions and actions. /// </summary> /// <returns></returns> public ActionResult EditFilter() { EditFilterRequest request = ApiRequestBase.ParseRequest <EditFilterRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { if (db.EditFilter(request.filter, out string errorMessage)) { Logger.Info("[" + p.Name + "] Filter " + request.filter.filter.FilterId + " (\"" + request.filter.filter.Name + "\") was edited by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); } else { return(ApiError(errorMessage)); } } }
public ActionResult DeleteAction() { OneFilterActionRequest request = ApiRequestBase.ParseRequest <OneFilterActionRequest>(this); if (!request.Validate(out Project p, out ApiResponseBase error)) { return(Json(error)); } using (DB db = new DB(p.Name)) { if (db.DeleteFilterAction(request.action.FilterActionId)) { Logger.Info("[" + p.Name + "] Filter action " + request.action.FilterActionId + " was deleted by \"" + session.userName + "\""); return(Json(new ApiResponseBase(true))); } else { return(ApiError("Unable to delete filter action " + request.action.FilterActionId)); } } }