mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Added filter label for human readable explanation.
Separated Username Cleaning logic. Updated Thunderbird auth method.
This commit is contained in:
parent
bd55b29de9
commit
ee3f7d8ee2
@ -43,6 +43,18 @@ namespace ServerMaint
|
||||
[Option('f', "last-seen-file", Required = false, HelpText = "The file in which you want the last seen stats to be saved to")]
|
||||
public string LastSeenFile { get; set; }
|
||||
|
||||
[Option('i', "invalid", DefaultValue = false, Required = false, HelpText = "Generate a list of invalid accounts")]
|
||||
public bool GenerateInvalid { get; set; }
|
||||
|
||||
[Option('t', "invalid-file", Required = false, HelpText = "The file in which you want the invalid accounts to be saved to")]
|
||||
public string InvalidFile { get; set; }
|
||||
|
||||
[Option('o', "to-clean", DefaultValue = false, Required = false, HelpText = "Generate a list of accounts to be cleaned")]
|
||||
public bool GenerateCleaning { get; set; }
|
||||
|
||||
[Option('n', "to-clean-file", Required = false, HelpText = "The file in which you want the accounts to be cleaned to be saved to")]
|
||||
public string CleaningFile { get; set; }
|
||||
|
||||
// Omitting long name, default --verbose
|
||||
[Option(HelpText = "Prints all messages to standard output.")]
|
||||
public bool Verbose { get; set; }
|
||||
|
@ -83,6 +83,18 @@ namespace ServerMaint
|
||||
GenerateLastSeen(config, db, options.LastSeenFile);
|
||||
}
|
||||
|
||||
// Generates a file for all of the invalid accounts
|
||||
if (options.GenerateInvalid)
|
||||
{
|
||||
GenerateInvalidAccounts(config, db, options.InvalidFile);
|
||||
}
|
||||
|
||||
// Generates a file for all of the accounts to be cleaned
|
||||
if (options.GenerateCleaning)
|
||||
{
|
||||
GenerateCleaningList(config, db, options.CleaningFile, options.DaysBeforeDeletion);
|
||||
}
|
||||
|
||||
Output(string.Format("[{0}] Finished Server Maintenance Process.", DateTime.Now));
|
||||
return 0;
|
||||
}
|
||||
@ -217,7 +229,7 @@ namespace ServerMaint
|
||||
mail.Body = string.Format(@"
|
||||
The account {0} does not meet the requirements for a valid username.
|
||||
|
||||
The username must match the following Regex Pattern: {1}
|
||||
The username must meet the following requirements: {1}
|
||||
It must also be greater than or equal to {2} characters in length, and less than or equal to {3} characters in length.
|
||||
|
||||
This email is to let you know that this account will be deleted in {4} days ({5}) in order to comply with the username restrictions. If you would like to keep your data, you should create a new account and transfer the data over to the new account.
|
||||
@ -226,7 +238,7 @@ In order to make the process as easy as possible, you can reply to this email to
|
||||
|
||||
Thank you for your continued use of Teknik!
|
||||
|
||||
- Teknik Administration", account, config.UserConfig.UsernameFilter, config.UserConfig.MinUsernameLength, config.UserConfig.MaxUsernameLength, 30, DateTime.Now.AddDays(30).ToShortDateString(), 15, DateTime.Now.AddDays(15).ToShortDateString());
|
||||
- Teknik Administration", account, config.UserConfig.UsernameFilterLabel, config.UserConfig.MinUsernameLength, config.UserConfig.MaxUsernameLength, 30, DateTime.Now.AddDays(30).ToShortDateString(), 15, DateTime.Now.AddDays(15).ToShortDateString());
|
||||
mail.BodyEncoding = UTF8Encoding.UTF8;
|
||||
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.Never;
|
||||
|
||||
@ -287,94 +299,56 @@ Thank you for your continued use of Teknik!
|
||||
|
||||
public static void CleanEmail(Config config, TeknikEntities db)
|
||||
{
|
||||
if (config.EmailConfig.Enabled)
|
||||
Output(string.Format("[{0}] Started Cleaning of Orphaned Email Accounts.", DateTime.Now));
|
||||
List<string> emails = GetOrphanedEmail(config, db);
|
||||
foreach (string email in emails)
|
||||
{
|
||||
Output(string.Format("[{0}] Started Cleaning of Orphaned Email Accounts.", DateTime.Now));
|
||||
List<User> curUsers = db.Users.ToList();
|
||||
int totalAccounts = 0;
|
||||
|
||||
// Connect to hmailserver COM
|
||||
var app = new hMailServer.Application();
|
||||
app.Connect();
|
||||
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);
|
||||
|
||||
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
|
||||
var accounts = domain.Accounts;
|
||||
for (int i = 0; i < accounts.Count; i++)
|
||||
{
|
||||
var account = accounts[i];
|
||||
|
||||
bool userExists = curUsers.Exists(u => UserHelper.GetUserEmailAddress(config, u.Username) == account.Address);
|
||||
bool isReserved = UserHelper.GetReservedUsernames(config).Exists(r => UserHelper.GetUserEmailAddress(config, r).ToLower() == account.Address.ToLower());
|
||||
if (!userExists && !isReserved)
|
||||
{
|
||||
// User doesn't exist, and it isn't reserved. Let's nuke it.
|
||||
UserHelper.DeleteUserEmail(config, account.Address);
|
||||
totalAccounts++;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalAccounts > 0)
|
||||
{
|
||||
// Add to transparency report if any users were removed
|
||||
Takedown report = db.Takedowns.Create();
|
||||
report.Requester = TAKEDOWN_REPORTER;
|
||||
report.RequesterContact = config.SupportEmail;
|
||||
report.DateRequested = DateTime.Now;
|
||||
report.Reason = "Orphaned Email Account";
|
||||
report.ActionTaken = string.Format("{0} Accounts Removed", totalAccounts);
|
||||
report.DateActionTaken = DateTime.Now;
|
||||
db.Takedowns.Add(report);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
Output(string.Format("[{0}] Finished Cleaning of Orphaned Email Accounts. {1} Accounts Removed.", DateTime.Now, totalAccounts));
|
||||
// User doesn't exist, and it isn't reserved. Let's nuke it.
|
||||
UserHelper.DeleteUserEmail(config, email);
|
||||
}
|
||||
|
||||
if (emails.Count > 0)
|
||||
{
|
||||
// Add to transparency report if any users were removed
|
||||
Takedown report = db.Takedowns.Create();
|
||||
report.Requester = TAKEDOWN_REPORTER;
|
||||
report.RequesterContact = config.SupportEmail;
|
||||
report.DateRequested = DateTime.Now;
|
||||
report.Reason = "Orphaned Email Account";
|
||||
report.ActionTaken = string.Format("{0} Accounts Removed", emails.Count);
|
||||
report.DateActionTaken = DateTime.Now;
|
||||
db.Takedowns.Add(report);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
Output(string.Format("[{0}] Finished Cleaning of Orphaned Email Accounts. {1} Accounts Removed.", DateTime.Now, emails.Count));
|
||||
}
|
||||
|
||||
public static void CleanGit(Config config, TeknikEntities db)
|
||||
{
|
||||
if (config.GitConfig.Enabled)
|
||||
Output(string.Format("[{0}] Started Cleaning of Orphaned Git Accounts.", DateTime.Now));
|
||||
List<string> gitAccounts = GetOrphanedGit(config, db);
|
||||
foreach (string account in gitAccounts)
|
||||
{
|
||||
Output(string.Format("[{0}] Started Cleaning of Orphaned Git Accounts.", DateTime.Now));
|
||||
List<User> curUsers = db.Users.ToList();
|
||||
int totalAccounts = 0;
|
||||
|
||||
// We need to check the actual git database
|
||||
MysqlDatabase mySQL = new MysqlDatabase(config.GitConfig.Database);
|
||||
string sql = @"SELECT gogs.user.login_name AS login_name, gogs.user.lower_name AS username FROM gogs.user";
|
||||
var results = mySQL.Query(sql);
|
||||
|
||||
if (results != null && results.Any())
|
||||
{
|
||||
foreach (var account in results)
|
||||
{
|
||||
bool userExists = curUsers.Exists(u => UserHelper.GetUserEmailAddress(config, u.Username).ToLower() == account["login_name"].ToString().ToLower());
|
||||
bool isReserved = UserHelper.GetReservedUsernames(config).Exists(r => UserHelper.GetUserEmailAddress(config, r) == account["login_name"].ToString().ToLower());
|
||||
if (!userExists && !isReserved)
|
||||
{
|
||||
UserHelper.DeleteUserGit(config, account["username"].ToString());
|
||||
totalAccounts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (totalAccounts > 0)
|
||||
{
|
||||
// Add to transparency report if any users were removed
|
||||
Takedown report = db.Takedowns.Create();
|
||||
report.Requester = TAKEDOWN_REPORTER;
|
||||
report.RequesterContact = config.SupportEmail;
|
||||
report.DateRequested = DateTime.Now;
|
||||
report.Reason = "Orphaned Git Account";
|
||||
report.ActionTaken = string.Format("{0} Accounts Removed", totalAccounts);
|
||||
report.DateActionTaken = DateTime.Now;
|
||||
db.Takedowns.Add(report);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
Output(string.Format("[{0}] Finished Cleaning of Orphaned Git Accounts. {1} Accounts Removed.", DateTime.Now, totalAccounts));
|
||||
// User doesn't exist, and it isn't reserved. Let's nuke it.
|
||||
UserHelper.DeleteUserGit(config, account);
|
||||
}
|
||||
|
||||
if (gitAccounts.Count > 0)
|
||||
{
|
||||
// Add to transparency report if any users were removed
|
||||
Takedown report = db.Takedowns.Create();
|
||||
report.Requester = TAKEDOWN_REPORTER;
|
||||
report.RequesterContact = config.SupportEmail;
|
||||
report.DateRequested = DateTime.Now;
|
||||
report.Reason = "Orphaned Git Account";
|
||||
report.ActionTaken = string.Format("{0} Accounts Removed", gitAccounts.Count);
|
||||
report.DateActionTaken = DateTime.Now;
|
||||
db.Takedowns.Add(report);
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
Output(string.Format("[{0}] Finished Cleaning of Orphaned Git Accounts. {1} Accounts Removed.", DateTime.Now, gitAccounts.Count));
|
||||
}
|
||||
|
||||
public static void GenerateLastSeen(Config config, TeknikEntities db, string fileName)
|
||||
@ -401,15 +375,107 @@ Thank you for your continued use of Teknik!
|
||||
Output(string.Format("[{0}] Finished Generating Last Activity List.", DateTime.Now));
|
||||
}
|
||||
|
||||
public static void GenerateInvalidAccounts(Config config, TeknikEntities db, string fileName)
|
||||
{
|
||||
Output(string.Format("[{0}] Started Generation of Invalid Account List.", DateTime.Now));
|
||||
List<string> invalidAccounts = GetInvalidAccounts(config, db);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Username,Last Activity,Creation Date,Last Website Activity,Last Email Activity,Last Git Activity");
|
||||
foreach (string account in invalidAccounts)
|
||||
{
|
||||
User user = UserHelper.GetUser(db, account);
|
||||
sb.AppendLine(string.Format("{0},{1},{2},{3},{4},{5}",
|
||||
user.Username,
|
||||
UserHelper.GetLastAccountActivity(db, config, user).ToString("g"),
|
||||
user.JoinDate.ToString("g"),
|
||||
user.LastSeen.ToString("g"),
|
||||
UserHelper.UserEmailLastActive(config, UserHelper.GetUserEmailAddress(config, user.Username)).ToString("g"),
|
||||
UserHelper.UserGitLastActive(config, user.Username).ToString("g")));
|
||||
}
|
||||
string dir = Path.GetDirectoryName(fileName);
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
File.WriteAllText(fileName, sb.ToString());
|
||||
Output(string.Format("[{0}] Finished Generating Invalid Account List.", DateTime.Now));
|
||||
}
|
||||
|
||||
public static void GenerateCleaningList(Config config, TeknikEntities db, string fileName, int maxDays)
|
||||
{
|
||||
Output(string.Format("[{0}] Started Generation of Accounts to Clean List.", DateTime.Now));
|
||||
List<string> invalidAccounts = GetInvalidAccounts(config, db);
|
||||
List<string> inactiveAccounts = GetInactiveAccounts(config, db, maxDays);
|
||||
List<string> emailAccounts = GetOrphanedEmail(config, db);
|
||||
List<string> gitAccounts = GetOrphanedGit(config, db);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Invalid Account Cleaning");
|
||||
sb.AppendLine("Username,Last Activity,Creation Date,Last Website Activity,Last Email Activity,Last Git Activity");
|
||||
foreach (string account in invalidAccounts)
|
||||
{
|
||||
User user = UserHelper.GetUser(db, account);
|
||||
sb.AppendLine(string.Format("{0},{1},{2},{3},{4},{5}",
|
||||
user.Username,
|
||||
UserHelper.GetLastAccountActivity(db, config, user).ToString("g"),
|
||||
user.JoinDate.ToString("g"),
|
||||
user.LastSeen.ToString("g"),
|
||||
UserHelper.UserEmailLastActive(config, UserHelper.GetUserEmailAddress(config, user.Username)).ToString("g"),
|
||||
UserHelper.UserGitLastActive(config, user.Username).ToString("g")));
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Inactive Account Cleaning");
|
||||
sb.AppendLine("Username,Last Activity,Creation Date,Last Website Activity,Last Email Activity,Last Git Activity");
|
||||
foreach (string account in inactiveAccounts)
|
||||
{
|
||||
User user = UserHelper.GetUser(db, account);
|
||||
sb.AppendLine(string.Format("{0},{1},{2},{3},{4},{5}",
|
||||
user.Username,
|
||||
UserHelper.GetLastAccountActivity(db, config, user).ToString("g"),
|
||||
user.JoinDate.ToString("g"),
|
||||
user.LastSeen.ToString("g"),
|
||||
UserHelper.UserEmailLastActive(config, UserHelper.GetUserEmailAddress(config, user.Username)).ToString("g"),
|
||||
UserHelper.UserGitLastActive(config, user.Username).ToString("g")));
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Orphaned Email Cleaning");
|
||||
sb.AppendLine("Email,Last Activity");
|
||||
foreach (string account in emailAccounts)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0},{1}",
|
||||
account,
|
||||
UserHelper.UserEmailLastActive(config, account).ToString("g")));
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Orphaned Git Cleaning");
|
||||
sb.AppendLine("Username,Last Activity");
|
||||
foreach (string account in gitAccounts)
|
||||
{
|
||||
sb.AppendLine(string.Format("{0},{1}",
|
||||
account,
|
||||
UserHelper.UserGitLastActive(config, account).ToString("g")));
|
||||
}
|
||||
|
||||
string dir = Path.GetDirectoryName(fileName);
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
File.WriteAllText(fileName, sb.ToString());
|
||||
Output(string.Format("[{0}] Finished Generating Accounts to Clean List.", DateTime.Now));
|
||||
}
|
||||
|
||||
public static List<string> GetInvalidAccounts(Config config, TeknikEntities db)
|
||||
{
|
||||
List<string> foundUsers = new List<string>();
|
||||
List<User> curUsers = db.Users.ToList();
|
||||
foreach (User user in curUsers)
|
||||
{
|
||||
// If the username is reserved, don't worry about it
|
||||
// If the username is reserved, let's add it to the list
|
||||
if (UserHelper.UsernameReserved(config, user.Username))
|
||||
{
|
||||
foundUsers.Add(user.Username);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -500,6 +566,63 @@ Thank you for your continued use of Teknik!
|
||||
return foundUsers;
|
||||
}
|
||||
|
||||
public static List<string> GetOrphanedEmail(Config config, TeknikEntities db)
|
||||
{
|
||||
List<string> foundEmail = new List<string>();
|
||||
if (config.EmailConfig.Enabled)
|
||||
{
|
||||
List<User> curUsers = db.Users.ToList();
|
||||
|
||||
// Connect to hmailserver COM
|
||||
var app = new hMailServer.Application();
|
||||
app.Connect();
|
||||
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);
|
||||
|
||||
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
|
||||
var accounts = domain.Accounts;
|
||||
for (int i = 0; i < accounts.Count; i++)
|
||||
{
|
||||
var account = accounts[i];
|
||||
|
||||
bool userExists = curUsers.Exists(u => UserHelper.GetUserEmailAddress(config, u.Username) == account.Address);
|
||||
bool isReserved = UserHelper.GetReservedUsernames(config).Exists(r => UserHelper.GetUserEmailAddress(config, r).ToLower() == account.Address.ToLower());
|
||||
if (!userExists && !isReserved)
|
||||
{
|
||||
foundEmail.Add(account.Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundEmail;
|
||||
}
|
||||
|
||||
public static List<string> GetOrphanedGit(Config config, TeknikEntities db)
|
||||
{
|
||||
List<string> foundGit = new List<string>();
|
||||
if (config.GitConfig.Enabled)
|
||||
{
|
||||
List<User> curUsers = db.Users.ToList();
|
||||
|
||||
// We need to check the actual git database
|
||||
MysqlDatabase mySQL = new MysqlDatabase(config.GitConfig.Database);
|
||||
string sql = @"SELECT gogs.user.login_name AS login_name, gogs.user.lower_name AS username FROM gogs.user";
|
||||
var results = mySQL.Query(sql);
|
||||
|
||||
if (results != null && results.Any())
|
||||
{
|
||||
foreach (var account in results)
|
||||
{
|
||||
bool userExists = curUsers.Exists(u => UserHelper.GetUserEmailAddress(config, u.Username).ToLower() == account["login_name"].ToString().ToLower());
|
||||
bool isReserved = UserHelper.GetReservedUsernames(config).Exists(r => UserHelper.GetUserEmailAddress(config, r) == account["login_name"].ToString().ToLower());
|
||||
if (!userExists && !isReserved)
|
||||
{
|
||||
foundGit.Add(account["username"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundGit;
|
||||
}
|
||||
|
||||
public static void Output(string message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
|
@ -49,7 +49,7 @@
|
||||
<li class="list-group-item">Port:<div class="pull-right"><b>143 (993 SSL)</b></div></li>
|
||||
<li class="list-group-item">User Name:<div class="pull-right"><b>@string.Format("[username]@{0}", Model.Config.EmailConfig.Domain)</b></div></li>
|
||||
<li class="list-group-item">Connection Security:<div class="pull-right"><b>None (SSL/TLS)</b></div></li>
|
||||
<li class="list-group-item">Authentication method:<div class="pull-right"><b>Password</b></div></li>
|
||||
<li class="list-group-item">Authentication method:<div class="pull-right"><b>Normal Password</b></div></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
@ -59,7 +59,7 @@
|
||||
<li class="list-group-item">Port:<div class="pull-right"><b>25 (465 SSL)</b></div></li>
|
||||
<li class="list-group-item">User Name:<div class="pull-right"><b>@string.Format("[username]@{0}", Model.Config.EmailConfig.Domain)</b></div></li>
|
||||
<li class="list-group-item">Connection Security:<div class="pull-right"><b>None (SSL/TLS)</b></div></li>
|
||||
<li class="list-group-item">Authentication method:<div class="pull-right"><b>Password</b></div></li>
|
||||
<li class="list-group-item">Authentication method:<div class="pull-right"><b>Normal Password</b></div></li>
|
||||
</ul>
|
||||
</div>
|
||||
</ul>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<li>Any Malware uploads or otherwise hosted/linked content will be removed without notice.</li>
|
||||
<li>Email is limited to a maximum of 100 outbound email messages per day. This is to prevent spam accounts. If your account is flagged as spamming, it will be deleted without notice.</li>
|
||||
<li>Copyrighted content will be removed only after a valid DMCA is recieved and verified.</li>
|
||||
<li>Inactive Accounts with no data will be deleted after 180 days.
|
||||
<li>Inactive Accounts with no data will be deleted after 365 days (1 Year).
|
||||
<ul>
|
||||
<li>Activity is defined as logging into the Teknik Website, into the Git website, into the mail service (Either through webmail or via another client), or Modifying/Adding a Git Repository.</li>
|
||||
<li>Data is defined as Blog Posts/Comments, Podcast Comments, Emails, and Git Repositories.</li>
|
||||
@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-10">
|
||||
<p><i>Last Modified May 18, 2016</i></p>
|
||||
<p><i>Last Modified May 19, 2016</i></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<p class="text-center">
|
||||
<small>
|
||||
Username must match the following pattern <var>@Model.Config.UserConfig.UsernameFilter</var><br />
|
||||
Username must meet the following requirements: <var>@Model.Config.UserConfig.UsernameFilterLabel</var><br />
|
||||
and the length must be greater than <b>@Model.Config.UserConfig.MinUsernameLength</b> and less than <b>@Model.Config.UserConfig.MaxUsernameLength</b> characters
|
||||
</small>
|
||||
</p>
|
||||
|
@ -11,6 +11,7 @@ namespace Teknik.Configuration
|
||||
public bool RegistrationEnabled { get; set; }
|
||||
public bool LoginEnabled { get; set; }
|
||||
public string UsernameFilter { get; set; }
|
||||
public string UsernameFilterLabel { get; set; }
|
||||
public int MinUsernameLength { get; set; }
|
||||
public int MaxUsernameLength { get; set; }
|
||||
public string ReservedUsernameDefinitionFile { get; set; }
|
||||
@ -20,6 +21,7 @@ namespace Teknik.Configuration
|
||||
RegistrationEnabled = true;
|
||||
LoginEnabled = true;
|
||||
UsernameFilter = "^[a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)*$";
|
||||
UsernameFilterLabel = "AlphaNumeric Characters with Dashes, Underlines, and 0-1 Periods not in the beginning or end.";
|
||||
MinUsernameLength = 1;
|
||||
MaxUsernameLength = 35;
|
||||
ReservedUsernameDefinitionFile = string.Empty;
|
||||
|
Loading…
Reference in New Issue
Block a user