예제 #1
0
        /// <summary>
        /// Checks if password has been compromised using PwnedPasswords API.
        /// </summary>
        /// <param name="password">Password to check</param>
        /// <returns>True if strong password, false if weak password</returns>
        public async Task <ResponseDto <bool> > IsPasswordValidAsync(string password)
        {
            var passwordHash = "";

            // Hash password with SHA1.
            using (var hasher = new SHA1Cng())
            {
                passwordHash = BitConverter.ToString(hasher.ComputeHash(Encoding.UTF8.GetBytes(password)));
                passwordHash = passwordHash.Replace("-", "");
            }

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            // Get first 5 characters of hash and send it as part of the url for a get request.
            var prefixHash   = passwordHash.Substring(0, 5);
            var request      = new GetRequestService($"{ApiConstants.PWNED_PASSWORD_URL}{prefixHash}");
            var response     = await new BackoffRequest(request).TryExecute();
            var responseBody = await response.Content.ReadAsStringAsync();

            // Separate response by lines into an array of strings
            var splitResponse = responseBody.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

            // Iterate through every line of response and check if hash matches and, if so, if the count
            // falls within valid range.
            foreach (var line in splitResponse)
            {
                // Splits the line by the hash suffix and the breach count.
                // An example line would be:
                // 1E4C9B93F3F0682250B6CF8331B7EE68FD8:3303003
                var splitLine  = line.Split(':');
                var suffixHash = splitLine[0];

                // If password hash does not match, continue to next iteration.
                if (!passwordHash.Equals(prefixHash + suffixHash.ToUpper()))
                {
                    continue;
                }

                var breachCount     = int.Parse(splitLine[1]);
                var isPasswordValid = true;

                // flag password as invalid if the breach count is greater than the limit
                if (breachCount > _maxValidCount)
                {
                    isPasswordValid = false;
                }

                return(new ResponseDto <bool>()
                {
                    Data = isPasswordValid
                });
            }

            // If password has has no matches, it is valid.
            return(new ResponseDto <bool>()
            {
                Data = true
            });
        }
예제 #2
0
        /// <summary>
        /// Calculates offset from UTC from geocoordinates using Google's Timezone API.
        /// </summary>
        /// <param name="coordinates">Coordinates of location to check time zone.</param>
        /// <returns>Offset of time (in seconds) from UTC.</returns>
        public async Task <ResponseDto <int> > GetOffsetAsync(IGeoCoordinates coordinates)
        {
            // Get current date in seconds to determine if its DST for Google's API.
            var baseTime  = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local);
            var timeStamp = (int)DateTime.Now.Subtract(baseTime).TotalSeconds;

            // Retrieve key from configuration and build url for get request.
            var key = ConfigurationManager.AppSettings[GoogleApiConstants.GOOGLE_TIMEZONE_API_KEYWORD];
            var url = BuildUrl(coordinates, key, timeStamp);

            // Send get request and parse response
            var request      = new GetRequestService(url);
            var response     = await new GoogleBackoffRequest(request).TryExecute();
            var responseJson = await response.Content.ReadAsStringAsync();

            var responseObj = JsonConvert.DeserializeObject <GoogleTimeZoneDto>(responseJson);

            if (responseObj.status != GoogleApiConstants.GOOGLE_GEOCODE_STATUS_OK)
            {
                if (responseObj.status == GoogleApiConstants.GOOGLE_TIMEZONE_STATUS_ZERO_RESULTS)
                {
                    return(new ResponseDto <int>()
                    {
                        Error = GoogleApiConstants.GOOGLE_TIMEZONE_ERROR_INVALID_ADDRESS
                    });
                }

                return(new ResponseDto <int>()
                {
                    Error = GoogleApiConstants.GOOGLE_TIMEZONE_ERROR_GENERAL
                });
            }

            return(new ResponseDto <int>()
            {
                Data = responseObj.rawOffset + responseObj.dstOffset
            });
        }
예제 #3
0
        /// <summary>
        /// Converts an address into geocoordinates using Google's Geocoding API.
        /// </summary>
        /// <param name="address">Address to geocode.</param>
        /// <returns>Coordinates of address.</returns>
        public async Task <ResponseDto <IGeoCoordinates> > GeocodeAsync(IAddress address)
        {
            try
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                // Retrieve key from configuration and build url for the get request.
                var key = ConfigurationManager.AppSettings[GoogleApiConstants.GOOGLE_GEOCODE_API_KEYWORD];
                var url = BuildUrl(address, key);

                // Send get request and parse the response
                var request      = new GetRequestService(url);
                var response     = await new GoogleBackoffRequest(request).TryExecute();
                var responseJson = await response.Content.ReadAsStringAsync();

                var responseObj = JsonConvert.DeserializeObject <GoogleGeocodingDto>(responseJson);

                if (responseObj.status != GoogleApiConstants.GOOGLE_GEOCODE_STATUS_OK)
                {
                    if (responseObj.status == GoogleApiConstants.GOOGLE_GEOCODE_STATUS_ZERO_RESULTS)
                    {
                        return(new ResponseDto <IGeoCoordinates>()
                        {
                            Error = GoogleApiConstants.GOOGLE_GEOCODE_ERROR_INVALID_ADDRESS
                        });
                    }

                    return(new ResponseDto <IGeoCoordinates>()
                    {
                        Error = GoogleApiConstants.GOOGLE_GEOCODE_ERROR_GENERAL
                    });
                }

                var result = responseObj.results[0];

                foreach (var addresses in responseObj.results[0].address_components)
                {
                    foreach (var type in addresses.types)
                    {
                        if (type != GoogleApiConstants.GOOGLE_GEOCODE_TYPE_STREET)
                        {
                            continue;
                        }

                        var lat            = result.geometry.location.lat;
                        var lng            = result.geometry.location.lng;
                        var geoCoordinates = new GeoCoordinates(lat, lng);

                        return(new ResponseDto <IGeoCoordinates>()
                        {
                            Data = geoCoordinates
                        });
                    }
                }

                return(new ResponseDto <IGeoCoordinates>()
                {
                    Error = GoogleApiConstants.GOOGLE_GEOCODE_ERROR_INVALID_ADDRESS
                });
            }
            catch
            {
                return(new ResponseDto <IGeoCoordinates>()
                {
                    Error = GoogleApiConstants.GOOGLE_GEOCODE_ERROR_GENERAL
                });
            }
        }