/// <summary> /// Handle data validation type exceptions /// </summary> /// <param name="context">The exception context</param> public override void OnException(ExceptionContext context) { var exception = context.Exception; // cast to shoc exception var shocException = exception as ShocException; // unknown error var errors = new List <ErrorDefinition> { ErrorDefinition.Unknown(Errors.UNKNOWN_ERROR) }; // if shoc exception consider getting internal errors if (shocException != null) { errors = shocException.Errors; } // build a result var result = new JsonResult(new AggregateErrorDefinition { Errors = errors }) { StatusCode = shocException == null ? 500 : 400 }; // return in the context context.Result = result; // mark error type context.HttpContext.Response.Headers["X-Shoc-Error"] = "aggregate"; }
public async Task <SignOutFlowResult> SignOutFlow(SignOutFlowInput input) { // get the context var context = await this.interaction.GetLogoutContextAsync(input.LogoutId); // valid context is required but not found if (input.RequireValidContext && context == null) { throw ErrorDefinition.Validation(IdentityErrors.HOTLINK_SIGNOUT).AsException(); } // sign out await this.HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme); // get signout iframe uri var signoutIframeUri = string.IsNullOrWhiteSpace(context?.SignOutIFrameUrl) ? null : new Uri(context.SignOutIFrameUrl); // return flow result return(new SignOutFlowResult { SignOutIframeUrl = signoutIframeUri?.PathAndQuery, PostLogoutRedirectUri = context?.PostLogoutRedirectUri ?? "/", ContinueFlow = context != null }); }
// internal static CfException LogError(EventLog eventLog, CfException ex, Db db) // { //string trace = Environment.StackTrace; // if (ex.StackTrace != null) // trace = ex.StackTrace; // else if (ex.InnerException != null && ex.InnerException.StackTrace != null) // trace = ex.InnerException.StackTrace; // EventLogError error = new EventLogError(); // error.EventLog = eventLog.Id; // error.Number = ex.Number; // error.Message = ex.Message; // error.StackTrace = trace; // EventLogErrorServices.Insert(error, db); //ErrorDefinition errorDefinition = new ErrorDefinition(); //errorDefinition.Message = ex.Message; //errorDefinition.LocalizedMessage = ResourceServices.GetString(Cf.Data.Resources.ResourceBase.Culture, "UI", "UnexpectedError"); ; //errorDefinition.LikeExpression = ex.Message; //errorDefinition = ErrorDefinitionServices.Insert(errorDefinition, db); //ex.ErrorDefinition = errorDefinition; // } internal static CfException LogError(EventLog eventLog, Exception ex, string module, Db db) { CfException exception = new CfException(module, eventLog.EventCategory, ex.Message, ex); string trace = Environment.StackTrace; if (exception.StackTrace != null) { trace = exception.StackTrace; } else if (exception.InnerException != null && exception.InnerException.StackTrace != null) { trace = exception.InnerException.StackTrace; } EventLogError error = new EventLogError(); error.EventLog = eventLog.Id; error.Number = exception.Number; error.Message = exception.Message; error.StackTrace = trace; EventLogErrorServices.Insert(error, db); ErrorDefinition errorDefinition = new ErrorDefinition(); errorDefinition.Message = exception.Message; errorDefinition.LocalizedMessage = ResourceServices.GetString(Cf.Data.Resources.ResourceBase.Culture, "UI", "UnexpectedError"); errorDefinition.LikeExpression = exception.Message; errorDefinition = ErrorDefinitionServices.Insert(errorDefinition, db); exception.ErrorDefinition = errorDefinition; return(exception); }
/// <summary> /// Create a new Error. /// Use a ErrorDefinition and ErrorType to create a new instance of an error Object. /// </summary> /// <param name="errorDefinition">Error definition from enumeration in ErrorManager class</param> /// <param name="errorType">Error type from enumeration in Error class</param> /// <returns>Error</returns> public static Error GetError(ErrorDefinition errorDefinition) { Error error = new Error(); error.ErrorMessage = errorDefinition.ToString(); error.ErrorCode = ((int)errorDefinition).ToString(); return(error); }
/// <summary> /// Sends the email message /// </summary> /// <param name="message">The message to send</param> /// <returns></returns> public async Task <EmailResult> SendAsync(EmailMessage message) { try { return(await this.SendImplAsync(message)); } catch (Exception e) { throw new ShocException(new List <ErrorDefinition> { ErrorDefinition.Unknown("MAILING_ERROR") }, "Could not send an email", e); } }
// GET: ErrorDefinition/Delete/5 public ActionResult Delete(Nullable <int> id) { if (id == null) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest)); } Db db = new Db(DbServices.ConnectionString); ErrorDefinition errorDefinition = ErrorDefinitionServices.Get(id.Value, db); if (errorDefinition == null) { return(HttpNotFound()); } return(View(errorDefinition)); }
/// <summary> /// Request a confirmation code for the given email /// </summary> /// <param name="httpContext">The HTTP context</param> /// <param name="user">The target user</param> /// <param name="request">The request</param> /// <returns></returns> public async Task <ConfirmationRequestResult> RequestConfirmation(HttpContext httpContext, UserModel user, ConfirmationRequest request) { // get existing codes var existingCodes = await this.userService.GetConfirmations(request.Email); // count existing active codes var existingActive = existingCodes.Count(c => c.ValidUntil >= DateTime.UtcNow); // check if exceeded if (existingActive > MAX_ACTIVE_CONFIRMATION_CODES) { throw ErrorDefinition.Validation(IdentityErrors.CONFIRMATION_REQUESTS_EXCEEDED).AsException(); } // get a fresh confirmation code (uppercase) var code = Rnd.GetString(CONFIRMATION_CODE_LENGTH).ToUpperInvariant(); // generate fresh validation link var link = Guid.NewGuid().ToString("N"); // calculate the hash of code var codeHash = this.passwordHasher.Hash(code).AsHash(); // build confirmation code entity var confirmation = await this.userService.CreateConfirmation(new ConfirmationCode { UserId = user.Id, Email = request.Email, CodeHash = codeHash, Link = link, ValidUntil = DateTime.UtcNow.Add(CONFIRMATION_CODE_LIFETIME), ReturnUrl = request.ReturnUrl, Created = DateTime.UtcNow }); // send notification var sent = await this.SendConfirmationCode(confirmation, code); // build result return(new ConfirmationRequestResult { Sent = sent }); }
/// <summary> /// Sign-in flow implementation /// </summary> /// <param name="httpContext">The HTTP Context</param> /// <param name="input">The sign-in input</param> /// <returns></returns> public async Task <SignInFlowResult> SignIn(HttpContext httpContext, SignInFlowInput input) { // gets the authorization context by the return URL (authorize callback URL) var context = await this.identityInteraction.GetAuthorizationContextAsync(input.ReturnUrl); // get the user by given email and password var validUser = await this.userService.EvaluateCredentials(input.Email, input.Password); // check if something went wrong while signin-in if (validUser.Errors.Count > 0 || validUser.Value == null) { await this.userService.SignInFailed(input.Email); throw new ShocException(validUser.Errors); } // get user from result var user = validUser.Value; // the users email is not verified report early if (!user.EmailVerified) { throw ErrorDefinition.Validation(IdentityErrors.UNVERIFIED_EMAIL).AsException(); } // do actual sign-in with given scheme await this.SignInImpl(httpContext, new SignInPrincipal { Subject = user.Id, Email = user.Email, DisplayName = validUser.Value.FullName, Provider = IdentityProviders.LOCAL, }); // the sign-in result return(new SignInFlowResult { Subject = validUser.Value.Id, ReturnUrl = input.ReturnUrl.IsBlank() || context == null ? "/" : input.ReturnUrl, ContinueFlow = context != null }); }
/// <summary> /// Request a confirmation code for the given email /// </summary> /// <param name="httpContext">The HTTP context</param> /// <param name="request">The confirmation request</param> /// <returns></returns> public async Task <ConfirmationRequestResult> RequestConfirmation(HttpContext httpContext, ConfirmationRequest request) { // gets the user by email var user = await this.userService.GetByEmail(request.Email); // check if no user if (user == null) { throw ErrorDefinition.Validation(IdentityErrors.NO_USER).AsException(); } // email is confirmed if (user.EmailVerified) { throw ErrorDefinition.Validation(IdentityErrors.EMAIL_ALREADY_CONFIRMED).AsException(); } // request for the user return(await this.RequestConfirmation(httpContext, user, request)); }
/// <summary> /// Initializes a new instance of the <see cref="PSErrorDefinition" /> class. /// </summary> /// <param name="error">The raw error definition.</param> public PSErrorDefinition(ErrorDefinition error) { if (error == null) { return; } this.Code = error.Code; this.Message = error.Message; this.Target = error.Target; if (error.Details != null) { this.Details = error.Details.Select(d => new PSErrorDefinition(d)); } if (error.AdditionalInfo != null) { this.AdditionalInfo = error.AdditionalInfo.Select(a => new PSTypedErrorInfo(a)); } }
public ActionResult Create([Bind(Include = "Id, Message, LocalizedMessage, LikeExpression")] ErrorDefinition errorDefinition) { Db db = new Db(DbServices.ConnectionString); if (ModelState.IsValid) { try { ErrorDefinitionServices.Insert(CurrentUser.Id, errorDefinition, db); TempData["Success"] = ResourceServices.GetString(Cf.Data.Resources.ResourceBase.Culture, "UI", "InsertConfirmed"); return(RedirectToAction("Index")); } catch (CfException cfex) { TempData["Failure"] = cfex.ErrorDefinition.LocalizedMessage; } catch (Exception ex) { TempData["Failure"] = ex.Message; } } return(View(errorDefinition)); }
/// <summary> /// Returns Error Description from Error Code /// </summary> /// <param name="Errorcode"></param> /// <returns></returns> public static string GetErrorMessage(int Errorcode) { ErrorDefinition error = (ErrorDefinition)Errorcode; return(error.ToString()); }
internal ErrorResponse(ErrorDefinition error) { Error = error; }
/// <summary> /// Process confirmation submit /// </summary> /// <param name="httpContext">The HTTP context</param> /// <param name="request">The confirmation process request</param> /// <returns></returns> public async Task <ConfirmationProcessResult> ProcessConfirmation(HttpContext httpContext, ConfirmationProcessRequest request) { // check if valid request if (request == null || request.Email.IsBlank()) { throw ErrorDefinition.Unknown(IdentityErrors.INVALID_EMAIL).AsException(); } // gets the authorization context by the return URL (authorize callback URL) var context = await this.identityInteraction.GetAuthorizationContextAsync(request.ReturnUrl); // the return url var returnUrl = request.ReturnUrl.IsBlank() || context == null ? "/" : request.ReturnUrl; // gets the user by email var user = await this.userService.GetByEmail(request.Email); // check if no user if (user == null) { throw ErrorDefinition.Validation(IdentityErrors.INVALID_EMAIL).AsException(); } // email is confirmed if (user.EmailVerified) { throw ErrorDefinition.Validation(IdentityErrors.EMAIL_ALREADY_CONFIRMED).AsException(); } // get codes for the target var codes = await this.userService.GetConfirmations(request.Email); // choose ones that are not expired var validCodes = codes.Where(c => c.ValidUntil >= DateTime.UtcNow); // check is valid var isValid = validCodes.Any(c => this.passwordHasher.Check(c.CodeHash, request.Code).Verified); // verification failed if (!isValid) { throw ErrorDefinition.Validation(IdentityErrors.INVALID_CONFIRMATION_CODE).AsException(); } // confirm otherwise user = await this.ProceedConfirmation(user); // do sign-in registration was successful await this.SignInImpl(httpContext, new SignInPrincipal { Subject = user.Id, Email = user.Email, DisplayName = user.FullName, Provider = IdentityProviders.LOCAL }); // build result return(new ConfirmationProcessResult { Subject = user.Id, ContinueFlow = context != null, ReturnUrl = returnUrl }); }
/// <summary> /// The sign-up operation based on input /// </summary> /// <param name="httpContext">The HTTP Context</param> /// <param name="input">The input for sign-up</param> /// <returns></returns> public async Task <SignUpFlowResult> SignUp(HttpContext httpContext, SignUpFlowInput input) { // check if can sign-up if (!this.signOnSettings.SignUpEnabled) { throw ErrorDefinition.Validation(IdentityErrors.SIGNUP_DISABLED).AsException(); } // gets the authorization context by the return URL (authorize callback URL) var context = await this.identityInteraction.GetAuthorizationContextAsync(input.ReturnUrl); // the return url var returnUrl = input.ReturnUrl.IsBlank() || context == null ? "/" : input.ReturnUrl; // validate email and password var validate = this.userService.ValidateEmailAndPassword(input.Email, input.Password); // failed validation if (validate.Count > 0) { throw new ShocException(validate); } // build a full name var fullname = input.FullName.IsBlank() ? "New User" : input.FullName; // try get root user if exists var root = await this.userService.GetRootUser(); // use guest role as default, if no root yet create as root var role = root == null ? Roles.ROOT : Roles.USER; // the email is not verified by default, in case if creating root email is already verified var emailVerified = root == null; // try create user based on given input var user = await this.userService.Create(new CreateUserModel { Email = input.Email, EmailVerified = emailVerified, FullName = fullname, Role = role, Password = input.Password }); // user is missing if (user == null) { throw ErrorDefinition.Validation(IdentityErrors.UNKNOWN_ERROR).AsException(); } // confirmation message sent var confirmationSent = false; // need to send email verification code message if (!user.EmailVerified) { try { var requestResult = await this.RequestConfirmation(httpContext, new ConfirmationRequest { Email = user.Email, ReturnUrl = returnUrl }); confirmationSent = requestResult.Sent; } catch (Exception) { confirmationSent = false; } } // sign in in case of verified email if (emailVerified) { // do sign-in registration was successful await this.SignInImpl(httpContext, new SignInPrincipal { Subject = user.Id, Email = user.Email, DisplayName = user.FullName, Provider = IdentityProviders.LOCAL }); } // build sign-up flow result return(new SignUpFlowResult { Subject = user.Id, Email = user.Email, EmailVerified = emailVerified, ConfirmationSent = confirmationSent, ContinueFlow = context != null, ReturnUrl = returnUrl }); }