mirror of
https://github.com/bitwarden/android.git
synced 2024-11-03 00:24:10 +03:00
178 lines
6.2 KiB
C#
178 lines
6.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Bit.App.Abstractions;
|
|
using Plugin.Settings.Abstractions;
|
|
|
|
namespace Bit.App.Services
|
|
{
|
|
public class PasswordGenerationService : IPasswordGenerationService
|
|
{
|
|
private readonly ISettings _settings;
|
|
private Random _random = new Random();
|
|
|
|
public PasswordGenerationService(ISettings settings)
|
|
{
|
|
_settings = settings;
|
|
}
|
|
|
|
public string GeneratePassword(
|
|
int? length = null,
|
|
bool? uppercase = null,
|
|
bool? lowercase = null,
|
|
bool? numbers = null,
|
|
bool? special = null,
|
|
bool? ambiguous = null,
|
|
int? minUppercase = null,
|
|
int? minLowercase = null,
|
|
int? minNumbers = null,
|
|
int? minSpecial = null)
|
|
{
|
|
int minUppercaseValue = minUppercase.GetValueOrDefault(1),
|
|
minLowercaseValue = minLowercase.GetValueOrDefault(1),
|
|
minNumbersValue = minNumbers.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorMinNumbers, 1)),
|
|
minSpecialValue = minSpecial.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorMinSpecial, 1)),
|
|
lengthValue = length.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10));
|
|
|
|
bool uppercaseValue = uppercase.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorUppercase, true)),
|
|
lowercaseValue = lowercase.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorLowercase, true)),
|
|
numbersValue = numbers.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorNumbers, true)),
|
|
specialValue = special.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorSpecial, true)),
|
|
ambiguousValue = ambiguous.GetValueOrDefault(_settings.GetValueOrDefault(Constants.PasswordGeneratorAmbiguous, false));
|
|
|
|
// Sanitize
|
|
if(uppercaseValue && minUppercaseValue < 0)
|
|
{
|
|
minUppercaseValue = 1;
|
|
}
|
|
if(lowercaseValue && minLowercaseValue < 0)
|
|
{
|
|
minLowercaseValue = 1;
|
|
}
|
|
if(numbersValue && minNumbersValue < 0)
|
|
{
|
|
minNumbersValue = 1;
|
|
}
|
|
if(specialValue && minSpecialValue < 0)
|
|
{
|
|
minSpecialValue = 1;
|
|
}
|
|
|
|
if(lengthValue < 1)
|
|
{
|
|
lengthValue = 10;
|
|
}
|
|
var minLength = minUppercaseValue + minLowercaseValue + minNumbersValue + minSpecialValue;
|
|
if(lengthValue < minLength)
|
|
{
|
|
lengthValue = minLength;
|
|
}
|
|
|
|
var positionsBuilder = new StringBuilder();
|
|
if(lowercaseValue && minLowercaseValue > 0)
|
|
{
|
|
for(int i = 0; i < minLowercaseValue; i++)
|
|
{
|
|
positionsBuilder.Append("l");
|
|
}
|
|
}
|
|
if(uppercaseValue && minUppercaseValue > 0)
|
|
{
|
|
for(int i = 0; i < minUppercaseValue; i++)
|
|
{
|
|
positionsBuilder.Append("u");
|
|
}
|
|
}
|
|
if(numbersValue && minNumbersValue > 0)
|
|
{
|
|
for(int i = 0; i < minNumbersValue; i++)
|
|
{
|
|
positionsBuilder.Append("n");
|
|
}
|
|
}
|
|
if(specialValue && minSpecialValue > 0)
|
|
{
|
|
for(int i = 0; i < minSpecialValue; i++)
|
|
{
|
|
positionsBuilder.Append("s");
|
|
}
|
|
}
|
|
while(positionsBuilder.Length < lengthValue)
|
|
{
|
|
positionsBuilder.Append("a");
|
|
}
|
|
|
|
// Shuffle
|
|
var positions = positionsBuilder.ToString().ToCharArray().OrderBy(a => _random.Next()).ToArray();
|
|
|
|
// Build out other character sets
|
|
var allCharSet = string.Empty;
|
|
|
|
var lowercaseCharSet = "abcdefghijkmnopqrstuvwxyz";
|
|
if(ambiguousValue)
|
|
{
|
|
lowercaseCharSet = string.Concat(lowercaseCharSet, "l");
|
|
}
|
|
if(lowercaseValue)
|
|
{
|
|
allCharSet = string.Concat(allCharSet, lowercaseCharSet);
|
|
}
|
|
|
|
var uppercaseCharSet = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
|
|
if(ambiguousValue)
|
|
{
|
|
uppercaseCharSet = string.Concat(uppercaseCharSet, "O");
|
|
}
|
|
if(uppercaseValue)
|
|
{
|
|
allCharSet = string.Concat(allCharSet, uppercaseCharSet);
|
|
}
|
|
|
|
var numberCharSet = "23456789";
|
|
if(ambiguousValue)
|
|
{
|
|
numberCharSet = string.Concat(numberCharSet, "01");
|
|
}
|
|
if(numbersValue)
|
|
{
|
|
allCharSet = string.Concat(allCharSet, numberCharSet);
|
|
}
|
|
|
|
var specialCharSet = "!@#$%^&*";
|
|
if(specialValue)
|
|
{
|
|
allCharSet = string.Concat(allCharSet, specialCharSet);
|
|
}
|
|
|
|
var password = new StringBuilder();
|
|
for(var i = 0; i < lengthValue; i++)
|
|
{
|
|
string positionChars = string.Empty;
|
|
switch(positions[i])
|
|
{
|
|
case 'l':
|
|
positionChars = lowercaseCharSet;
|
|
break;
|
|
case 'u':
|
|
positionChars = uppercaseCharSet;
|
|
break;
|
|
case 'n':
|
|
positionChars = numberCharSet;
|
|
break;
|
|
case 's':
|
|
positionChars = specialCharSet;
|
|
break;
|
|
case 'a':
|
|
positionChars = allCharSet;
|
|
break;
|
|
}
|
|
|
|
var randomCharIndex = _random.Next(0, positionChars.Length - 1);
|
|
password.Append(positionChars[randomCharIndex]);
|
|
}
|
|
|
|
return password.ToString();
|
|
}
|
|
}
|
|
}
|