public async Task <GetProfileResponse> Handle(GetProfileRequest request, CancellationToken cancellationToken)
        {
            var user = await _userAccountRepository.GetUserAccountAsync(request.User);

            var userFeeds = await _userFeedRepository.GetAsync(user);

            var apiAccesses = await _userAccountApiAccessRepository.GetAsync(user);

            var externalApiAccessModels = new List <ExternalApiAccessModel>();

            foreach (var apiAccess in apiAccesses)
            {
                var mostRecentToken = await _userAccountTokenRepository.GetLatestAsync(apiAccess);

                var lastAccessed = mostRecentToken?.CreatedDateTime ?? apiAccess.CreatedDateTime;
                externalApiAccessModels.Add(new ExternalApiAccessModel(apiAccess.UserAccountApiAccessId, apiAccess.ApiClient.DisplayName, apiAccess.CreatedDateTime, lastAccessed, apiAccess.RevokedDateTime));
            }

            var externalApiClients = await _apiClientRepository.GetAsync(user);

            return(new GetProfileResponse(
                       userFeeds.Select(uf => new FeedModel(uf.UserFeedId, uf.UserFeedIdentifier, uf.CreatedDateTime, uf.FeedType, uf.ItemDisplay)),
                       externalApiAccessModels.OrderByDescending(a => a.RevokedDateTime ?? DateTime.MaxValue).ThenByDescending(a => a.LastAccessedDateTime),
                       externalApiClients.OrderBy(a => a.DisplayName).Select(a => new ExternalApiClientModel(
                                                                                 a.ApiClientId, a.DisplayName, a.AppKey, a.RedirectUri, a.IsEnabled
                                                                                 ))));
        }
示例#2
0
        public async Task <GetAccessTokenResponse> Handle(ValidateCredentialsAndCreateAccessTokenRequest request, CancellationToken cancellationToken)
        {
            var credentialBytes = Convert.FromBase64String(request.Credentials);
            var credentials     = Encoding.UTF8.GetString(credentialBytes).Split(':', 2);

            if (credentials.Length != 2)
            {
                _logger.LogInformation($"Invalid auth header [{request.Credentials}] - expected 'Basic appkey:appsecret'");
                return(null);
            }

            var apiClient = await _apiClientRepository.GetAsync(credentials[0]);

            if (apiClient == null)
            {
                _logger.LogInformation($"Could not find api client for appkey [{credentials[0]}]");
                return(null);
            }

            if (SaltHashHelper.CreateHash(credentials[1], apiClient.AppSecretSalt) != apiClient.AppSecretHash)
            {
                _logger.LogInformation($"Invalid login attempt");
                return(null);
            }

            var userAccountApiAccess = await _userAccountApiAccessRepository.GetByRefreshTokenAsync(request.RefreshToken);

            if (userAccountApiAccess == null)
            {
                _logger.LogInformation($"Unknown refresh token: {request.RefreshToken}");
                return(null);
            }

            if (userAccountApiAccess.RevokedDateTime != null)
            {
                _logger.LogInformation($"API Access has been revoked");
                return(new GetAccessTokenResponse("user_revoked", null));
            }

            var tokenData   = GuidString.NewGuidString();
            var tokenExpiry = DateTime.UtcNow.AddMinutes(30);
            await _userAccountTokenRepository.CreateAsync(userAccountApiAccess, tokenData, tokenExpiry);

            var tokenOptions = _configuration.GetSection("SmallListerApiJwt");
            var signingKey   = tokenOptions.GetValue("SigningKey", "");
            var issuer       = tokenOptions.GetValue("Issuer", "");
            var audience     = tokenOptions.GetValue("Audience", "");

            var tokenHandler            = new JwtSecurityTokenHandler();
            var securityTokenDescriptor = new SecurityTokenDescriptor
            {
                Subject            = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, tokenData) }),
                Audience           = audience,
                Issuer             = issuer,
                Expires            = tokenExpiry,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey)), SecurityAlgorithms.HmacSha256Signature)
            };

            return(new GetAccessTokenResponse(null, tokenHandler.WriteToken(tokenHandler.CreateToken(securityTokenDescriptor))));
        }
        public async Task <string> Handle(ApiAuthorizeRequest request, CancellationToken cancellationToken)
        {
            if (!Uri.TryCreate(request.Model.RedirectUri, UriKind.Absolute, out var redirectUri))
            {
                return(null);
            }

            if (!request.Model.AllowApiAuth)
            {
                return(GetRedirectUri("errorCode=user_declined"));
            }

            var apiClient = await _apiClientRepository.GetAsync(request.Model.AppKey);

            if (apiClient == null)
            {
                _logger.LogInformation($"Cannot find api client {request.Model.AppKey} with redirect uri {request.Model.RedirectUri}");
                return(null);
            }

            if (apiClient.RedirectUri != request.Model.RedirectUri)
            {
                _logger.LogInformation($"Api client {apiClient.AppKey} redirect uri {apiClient.RedirectUri} does not match request {request.Model.RedirectUri}");
                return(null);
            }

            if (!apiClient.IsEnabled)
            {
                _logger.LogInformation($"Api client {apiClient.AppKey} is not enabled");
                return(null);
            }

            var refreshToken = GuidString.NewGuidString();
            await _userAccountApiAccessRepository.Create(apiClient, await _userAccountRepository.GetUserAccountAsync(request.User), refreshToken);

            return(GetRedirectUri($"refreshToken={refreshToken}"));

            string GetRedirectUri(string returnInfo) => $"{redirectUri}{(string.IsNullOrEmpty(redirectUri.Query) ? "?" : "&")}{returnInfo}";
        }
        public async Task <bool> Handle(UpdateExternalClientRequest request, CancellationToken cancellationToken)
        {
            var user = await _userAccountRepository.GetUserAccountAsync(request.User);

            var apiClient = await _apiClientRepository.GetAsync(request.ApiClientId);

            if (apiClient == null)
            {
                _logger.LogInformation($"Could not find api client {request.ApiClientId}");
                return(false);
            }

            if (apiClient.CreatedById != user.UserAccountId)
            {
                _logger.LogInformation($"Api client {apiClient.ApiClientId} is not owned by {user.UserAccountId} - cannot update");
                return(false);
            }

            apiClient.IsEnabled = request.State == "enable";
            await _apiClientRepository.UpdateAsync(apiClient);

            return(true);
        }
示例#5
0
        public async Task <GetApiAuthorizeResponse> Handle(GetApiAuthorizeRequest request, CancellationToken cancellationToken)
        {
            var apiClient = await _apiClientRepository.GetAsync(request.AppKey);

            if (apiClient == null)
            {
                _logger.LogInformation($"Cannot find api client {request.AppKey} with redirect uri {request.RedirectUri}");
                return(GetApiAuthorizeResponse.InvalidResponse);
            }

            if (apiClient.RedirectUri != request.RedirectUri)
            {
                _logger.LogInformation($"Api client {apiClient.AppKey} redirect uri {apiClient.RedirectUri} does not match request {request.RedirectUri}");
                return(GetApiAuthorizeResponse.InvalidResponse);
            }

            if (!apiClient.IsEnabled)
            {
                _logger.LogInformation($"Api client {apiClient.AppKey} is not enabled");
                return(GetApiAuthorizeResponse.InvalidResponse);
            }

            return(new GetApiAuthorizeResponse(apiClient.AppKey, apiClient.RedirectUri, apiClient.DisplayName));
        }