예제 #1
0
        public async Task <IActionResult> DeleteUserVisit(int user, string visit)
        {
            IActionResult response = null;

            this._logger.LogInformation(LoggingEvents.DELETE_USER_VISIT, "Delete user visit for userId={user} and visitId={visit}", user, visit);
            var claims = this.ExtractClaimsFromAuthorizationHeaderBearerToken(this.Request.Headers);

            //NOTE: Right now this always evaluates to true, because the BearerTokenDecryptor is hard coded to
            //return this claim.
            if (ClaimsChecker.IsAllowed("DELETE", "*", claims))
            {
                await this.VisitsRepository.DeleteVisit(user, visit);

                //200 OK is always returned unless there is an internal server error, because this is an
                //idempotent call. If there is an error, the framework will auto reply with 500 internal server error.
                response = this.Ok();
            }
            else
            {
                this._logger.LogWarning(LoggingEvents.DELETE_USER_VISIT, "Unauthorized attempt to delete user visit for userId={user} and visitId={visit}", user, visit);
                response = this.Unauthorized();
            }

            return(response);
        }
예제 #2
0
        public async Task <IActionResult> PostUserVisit(int user, [FromBody] PostVisitRepresentation visit)
        {
            IActionResult response = null;

            this._logger.LogInformation(LoggingEvents.POST_USER_VISIT, "Post user visit for userId={user}", user);
            var claims = this.ExtractClaimsFromAuthorizationHeaderBearerToken(this.Request.Headers);

            //NOTE: Right now this always evaluates to true, because the BearerTokenDecryptor is hard coded to
            //return this claim.
            if (ClaimsChecker.IsAllowed("POST", "*", claims))
            {
                var claimsUserId = this.ExtractClaimsUserId(claims);
                if (claimsUserId.HasValue && user == claimsUserId.Value)
                {
                    //Validate input data
                    if (!string.IsNullOrWhiteSpace(visit.City) && visit.City.Length <= MAXCITYLENGTH &&
                        !string.IsNullOrWhiteSpace(visit.State) && visit.State.Length == MAXSTATELENGTH)
                    {
                        //TODO: Add rate limiting check here, so even if a valid user submits valid data,
                        //they can't create hundreds of these per minute, because it's expected to come
                        //from a real end user and not an automated system. If a backend system does call
                        //this API then the rate limiting can be made smarter or relaxed to a very large number.

                        var tasks     = new List <Task>();
                        var stateTask = this.GeographyRepository.GetStateByAbbreviationAsync(visit.State);
                        tasks.Add(stateTask);
                        var cityTask = this.GeographyRepository.GetCityAsync(visit.State, visit.City);
                        tasks.Add(cityTask);
                        var state = stateTask.Result;
                        var city  = cityTask.Result;

                        //Do all these tasks at once and wait for all to complete.
                        await Task.WhenAll(tasks);

                        //Persist to the repository
                        var userVisit = new Visit()
                        {
                            Created = DateTime.UtcNow,
                            User    = user,
                            CityId  = city.CityId,
                            StateId = state.StateId,
                            VisitId = Guid.NewGuid().ToString()
                        };
                        await this.VisitsRepository.SaveVisit(userVisit);


                        //Convert to representation.
                        var visitRepresentation = new VisitRepresentation()
                        {
                            City    = city.Name,
                            Created = userVisit.Created,
                            State   = state.Abbreviation,
                            User    = user,
                            VisitId = userVisit.VisitId,
                            Links   = new VisitRepresentationLinks()
                            {
                                Self = new Link()
                                {
                                    Href = string.Format("/user/{0}/visit/{1}", userVisit.User, userVisit.VisitId)
                                }
                            }
                        };

                        response = this.Ok(visitRepresentation);
                    }
                    else
                    {
                        response = this.BadRequest("City or state too long. Use city name and state abbreviation.");
                    }
                }
                else
                {
                    this._logger.LogWarning(LoggingEvents.POST_USER_VISIT, "Unauthorized attempt to post user visit for userId={user}", user);
                    response = this.Unauthorized();
                }
            }
            else
            {
                this._logger.LogWarning(LoggingEvents.POST_USER_VISIT, "Unauthorized attempt to post user visit for userId={user}", user);
                response = this.Unauthorized();
            }

            return(response);
        }