public async Task <ActionResult <GetPermissionResponse> > GetPermission(string meUserId, string permissionId)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(new GetPermissionResponse()));
            }

            try
            {
                var user = await _userRetrievalByIdService.Handle(new UserRetrievalByIdQuery(meUserId));

                if (user == null)
                {
                    return(NotFound(new GetPermissionResponse()));
                }

                var permission = user.Permissions.FirstOrDefault(p => p.PermissionId == permissionId);

                if (permission == null)
                {
                    return(NotFound(new GetPermissionResponse()));
                }

                var locationDocument = (await
                                        _locationParentsService.Handle(
                                            new LocationParentsQuery(permission.LocationId)))
                                       .ToLocationPath();

                if (!CanAsync(Permission.GetUserPermission, locationDocument))
                {
                    return(Forbid());
                }

                var location = await permission.GetLocationName(_locationsRetrievalByIdService);

                var permissionLocations = new PermissionLocation(permission, location, meUserId);

                var result = Mapper.Map <GetPermissionResponse>(permissionLocations);
                return(Ok(result));
            }
            catch (ArgumentException)
            {
                return(NotFound(new GetPermissionResponse()));
            }
            catch (NullReferenceException)
            {
                return(NotFound(new GetPermissionResponse()));
            }
        }
        public async Task <ActionResult <PutPermissionResponse> > UpdatePermission(
            [Required] string meUserId,
            [Required] string permissionId,
            [FromBody]
            PutPermissionRequest putPermission)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(new PutPermissionResponse()));
                }

                var currentUser = await CurrentUser();

                if (currentUser.UserId.Equals(meUserId))
                {
                    return(Forbid());
                }

                var locationDocument = (await
                                        _locationParentsService.Handle(
                                            new LocationParentsQuery(putPermission.LocationId)))
                                       .ToLocationPath();

                if (!CanAsync(Permission.UpdateUserPermission, locationDocument))
                {
                    return(Forbid());
                }

                var user = await _userRetrievalByIdService.Handle(new UserRetrievalByIdQuery(meUserId));

                if (user == null)
                {
                    return(NotFound(new PutPermissionResponse()));
                }

                var permissionToUpdate = user.Permissions.SingleOrDefault(p => p.PermissionId == permissionId);

                if (permissionToUpdate == null)
                {
                    return(NotFound(new PutPermissionResponse()));
                }

                if (user.Permissions.Any(usersPermission => usersPermission.LocationId == putPermission.LocationId && usersPermission.UserRole == putPermission.UserRole))
                {
                    return(Conflict());
                }

                permissionToUpdate = Mapper.Map(putPermission, permissionToUpdate);

                var updateUser = new UserUpdatePermissions
                {
                    UserId      = user.UserId,
                    Permissions = user.Permissions,
                };

                await _userUpdateService.Handle(new UserUpdateQuery(updateUser, currentUser));

                var locationOfPermission =
                    _locationRetrievalService.Handle(new LocationRetrievalByIdQuery(permissionToUpdate.LocationId)).Result;

                var permissionLocation = new PermissionLocation(permissionToUpdate, locationOfPermission, meUserId);

                var result = Mapper.Map <PutPermissionResponse>(permissionLocation);

                return(Ok(result));
            }
            catch (DocumentClientException)
            {
                return(NotFound(new PutPermissionResponse()));
            }
            catch (ArgumentException)
            {
                return(NotFound(new PutPermissionResponse()));
            }
        }
        public async Task <ActionResult <PostPermissionResponse> > CreatePermission(
            [Required] string meUserId,
            [FromBody]
            PostPermissionRequest postPermission)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(new PostPermissionResponse()));
            }

            var currentUser = await CurrentUser();

            if (currentUser.UserId.Equals(meUserId))
            {
                return(Forbid());
            }

            try
            {
                var permission = Mapper.Map <MEUserPermission>(postPermission);
                permission.PermissionId = Guid.NewGuid().ToString();

                var locationDocument = (await
                                        _locationParentsService.Handle(
                                            new LocationParentsQuery(permission.LocationId)))
                                       .ToLocationPath();

                if (!CanAsync(Permission.CreateUserPermission, locationDocument))
                {
                    return(Forbid());
                }

                var user = await _userRetrievalByIdService.Handle(new UserRetrievalByIdQuery(meUserId));

                if (user == null)
                {
                    return(NotFound(new PostPermissionResponse()));
                }

                var existingPermissions = user.Permissions != null?user.Permissions.ToList() : new List <MEUserPermission>();

                if (user.Permissions == null)
                {
                    user.Permissions = new List <MEUserPermission>();
                }

                if (user.Permissions.Any(usersPermissions => usersPermissions.IsEquivalent(permission)))
                {
                    return(Conflict());
                }

                existingPermissions.Add(permission);

                user.Permissions = existingPermissions;

                var updateUser = new UserUpdatePermissions
                {
                    UserId      = user.UserId,
                    Permissions = user.Permissions,
                };

                await _userUpdateService.Handle(new UserUpdateQuery(updateUser, currentUser));

                var location = _locationRetrievalService.Handle(new LocationRetrievalByIdQuery(permission.LocationId)).Result;

                var permissionLocation = new PermissionLocation(permission, location, meUserId);

                var result = Mapper.Map <PostPermissionResponse>(permissionLocation);
                return(Ok(result));
            }
            catch (DocumentClientException)
            {
                return(NotFound(new PostPermissionResponse()));
            }
            catch (ArgumentException)
            {
                return(NotFound(new PostPermissionResponse()));
            }
        }