Browse Source

- Moved git and email management to their own functions.

- Added deletion of account on email or git account missing.
- Added exception deep message generation extension.
- Added better exception handling to user management.
- Cleaned up user management functions.
tags/2.0.3
Teknikode 3 years ago
parent
commit
89683efcad

+ 26
- 2
ServerMaint/Program.cs View File

@@ -73,7 +73,7 @@ namespace ServerMaint
}
catch (Exception ex)
{
string msg = string.Format("[{0}] Exception: {1}", DateTime.Now, ex.Message);
string msg = string.Format("[{0}] Exception: {1}", DateTime.Now, ex.GetFullMessage(true));
File.AppendAllLines(errorFile, new List<string> { msg });
Output(msg);
}
@@ -166,6 +166,13 @@ namespace ServerMaint
List<User> curUsers = db.Users.ToList();
foreach (User user in curUsers)
{
// If the username isn't valid, don't clean it (Reserved, not formatted correctly, etc)
if (!UserHelper.ValidUsername(db, config, user.Username))
{
continue;
}

#region Inactivity Cleaning
DateTime lastActivity = UserHelper.GetLastActivity(db, config, user);

TimeSpan inactiveTime = DateTime.Now.Subtract(lastActivity);
@@ -181,7 +188,7 @@ namespace ServerMaint
int daysForEmail = (int)Math.Floor((double)(maxDays / (numEmails + 1)));
for (int i = daysForEmail; i < maxDays; i = i + daysForEmail)
{
if (inactiveTime.Days == daysForEmail)
if (inactiveTime.Days == i)
{
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
// Let's send them an email
@@ -211,6 +218,23 @@ Thank you for your use of Teknik and I hope you decide to come back.
break;
}
}
#endregion

#region Missing Email Accounts
if (!UserHelper.UserEmailExists(config, user.Username))
{
// They are missing an email account. Something bad happened, so let's delete their account so they can start over. :D
UserHelper.DeleteUser(db, config, user);
}
#endregion

#region Missing Git Accounts
if (!UserHelper.UserGitExists(config, user.Username))
{
// They are missing a git account. Something bad happened, so let's delete their account so they can start over. :D
UserHelper.DeleteUser(db, config, user);
}
#endregion
}

// Add to transparency report if any users were removed

+ 89
- 69
Teknik/Areas/User/Controllers/UserController.cs View File

@@ -39,36 +39,44 @@ namespace Teknik.Areas.Users.Controllers
ViewBag.Title = "User Does Not Exist - " + Config.Title;
ViewBag.Description = "The User does not exist";

User user = db.Users.Where(u => u.Username == username).FirstOrDefault();

if (user != null)
try
{
ViewBag.Title = username + "'s Profile - " + Config.Title;
ViewBag.Description = "Viewing " + username + "'s Profile";
model.UserID = user.UserId;
model.Username = user.Username;
if (Config.EmailConfig.Enabled)
User user = db.Users.Where(u => u.Username == username).FirstOrDefault();

if (user != null)
{
model.Email = string.Format("{0}@{1}", user.Username, Config.EmailConfig.Domain);
}
model.JoinDate = user.JoinDate;
model.LastSeen = UserHelper.GetLastActivity(db, Config, user);
ViewBag.Title = username + "'s Profile - " + Config.Title;
ViewBag.Description = "Viewing " + username + "'s Profile";

model.UserSettings = user.UserSettings;
model.BlogSettings = user.BlogSettings;
model.UploadSettings = user.UploadSettings;
model.UserID = user.UserId;
model.Username = user.Username;
if (Config.EmailConfig.Enabled)
{
model.Email = string.Format("{0}@{1}", user.Username, Config.EmailConfig.Domain);
}
model.JoinDate = user.JoinDate;
model.LastSeen = UserHelper.GetLastActivity(db, Config, user);

model.Uploads = db.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList();
model.UserSettings = user.UserSettings;
model.BlogSettings = user.BlogSettings;
model.UploadSettings = user.UploadSettings;

model.Pastes = db.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList();
model.Uploads = db.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList();

model.ShortenedUrls = db.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList();
model.Pastes = db.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList();

return View(model);
model.ShortenedUrls = db.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList();

return View(model);
}
model.Error = true;
model.ErrorMessage = "The user does not exist";
}
catch (Exception ex)
{
model.Error = true;
model.ErrorMessage = ex.GetFullMessage(true);
}
model.Error = true;
model.ErrorMessage = "The user does not exist";
return View(model);
}
@@ -210,9 +218,9 @@ namespace Teknik.Areas.Users.Controllers
{
if (Config.UserConfig.RegistrationEnabled)
{
if (UserHelper.UserExists(db, model.Username))
if (UserHelper.UsernameAvailable(db, Config, model.Username))
{
return Json(new { error = "That username already exists." });
return Json(new { error = "That username is not available." });
}
if (model.Password != model.ConfirmPassword)
{
@@ -224,7 +232,6 @@ namespace Teknik.Areas.Users.Controllers
User newUser = db.Users.Create();
newUser.JoinDate = DateTime.Now;
newUser.Username = model.Username;
newUser.HashedPassword = SHA384.Hash(model.Username, model.Password);
newUser.UserSettings = new UserSettings();
newUser.BlogSettings = new BlogSettings();
newUser.UploadSettings = new UploadSettings();
@@ -233,7 +240,7 @@ namespace Teknik.Areas.Users.Controllers
}
catch (Exception ex)
{
return Json(new { error = ex.Message });
return Json(new { error = ex.GetFullMessage(true) });
}
return Login(new LoginViewModel { Username = model.Username, Password = model.Password, RememberMe = false, ReturnUrl = model.ReturnUrl });
}
@@ -247,48 +254,54 @@ namespace Teknik.Areas.Users.Controllers
{
if (ModelState.IsValid)
{
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
try
{
bool changePass = false;
string email = string.Format("{0}@{1}", User.Identity.Name, Config.EmailConfig.Domain);
// Changing Password?
if (!string.IsNullOrEmpty(curPass) && (!string.IsNullOrEmpty(newPass) || !string.IsNullOrEmpty(newPassConfirm)))
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
// Old Password Valid?
if (SHA384.Hash(User.Identity.Name, curPass) != user.HashedPassword)
bool changePass = false;
string email = string.Format("{0}@{1}", User.Identity.Name, Config.EmailConfig.Domain);
// Changing Password?
if (!string.IsNullOrEmpty(curPass) && (!string.IsNullOrEmpty(newPass) || !string.IsNullOrEmpty(newPassConfirm)))
{
return Json(new { error = "Invalid Original Password." });
// Old Password Valid?
if (SHA384.Hash(User.Identity.Name, curPass) != user.HashedPassword)
{
return Json(new { error = "Invalid Original Password." });
}
// The New Password Match?
if (newPass != newPassConfirm)
{
return Json(new { error = "New Password Must Match." });
}
changePass = true;
}
// The New Password Match?
if (newPass != newPassConfirm)

// PGP Key valid?
if (!string.IsNullOrEmpty(pgpPublicKey) && !PGP.IsPublicKey(pgpPublicKey))
{
return Json(new { error = "New Password Must Match." });
return Json(new { error = "Invalid PGP Public Key" });
}
user.HashedPassword = SHA384.Hash(User.Identity.Name, newPass);
changePass = true;
}
user.UserSettings.PGPSignature = pgpPublicKey;

// PGP Key valid?
if (!string.IsNullOrEmpty(pgpPublicKey) && !PGP.IsPublicKey(pgpPublicKey))
{
return Json(new { error = "Invalid PGP Public Key" });
}
user.UserSettings.PGPSignature = pgpPublicKey;
user.UserSettings.Website = website;
user.UserSettings.Quote = quote;
user.UserSettings.About = about;

user.UserSettings.Website = website;
user.UserSettings.Quote = quote;
user.UserSettings.About = about;
user.BlogSettings.Title = blogTitle;
user.BlogSettings.Description = blogDesc;

user.BlogSettings.Title = blogTitle;
user.BlogSettings.Description = blogDesc;

user.UploadSettings.SaveKey = saveKey;
user.UploadSettings.ServerSideEncrypt = serverSideEncrypt;
UserHelper.SaveUser(db, Config, user, changePass, newPass);
return Json(new { result = true });
user.UploadSettings.SaveKey = saveKey;
user.UploadSettings.ServerSideEncrypt = serverSideEncrypt;
UserHelper.EditUser(db, Config, user, changePass, newPass);
return Json(new { result = true });
}
return Json(new { error = "User does not exist" });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
return Json(new { error = "User does not exist" });
}
return Json(new { error = "Invalid Parameters" });
}
@@ -298,20 +311,27 @@ namespace Teknik.Areas.Users.Controllers
{
if (ModelState.IsValid)
{
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
try
{
try
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
UserHelper.DeleteUser(db, Config, user);
}
catch (Exception ex)
{
return Json(new { error = ex.Message });
try
{
UserHelper.DeleteUser(db, Config, user);
}
catch (Exception ex)
{
return Json(new { error = ex.Message });
}
// Sign Out
Logout();
return Json(new { result = true });
}
// Sign Out
Logout();
return Json(new { result = true });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
}
return Json(new { error = "Unable to delete user" });

+ 339
- 162
Teknik/Areas/User/Utility/UserHelper.cs View File

@@ -19,6 +19,7 @@ namespace Teknik.Areas.Users.Utility
{
public static class UserHelper
{
#region User Management
public static User GetUser(TeknikEntities db, string username)
{
User user = db.Users.Where(b => b.Username == username).FirstOrDefault();
@@ -43,53 +44,66 @@ namespace Teknik.Areas.Users.Utility
return false;
}

public static void AddUser(TeknikEntities db, Config config, User user, string password)
public static bool ValidUsername(TeknikEntities db, Config config, string username)
{
bool isValid = true;

if (config.UserConfig.ReservedUsernames.Exists(u => u.ToLower() == username.ToLower()))
isValid = false;

return isValid;
}

public static bool UsernameAvailable(TeknikEntities db, Config config, string username)
{
bool isAvailable = true;

isAvailable &= ValidUsername(db, config, username);
isAvailable &= !UserExists(db, username);
isAvailable &= !UserEmailExists(config, username);
isAvailable &= !UserGitExists(config, username);

return isAvailable;
}

public static DateTime GetLastActivity(TeknikEntities db, Config config, User user)
{
try
{
DateTime lastActive = new DateTime(1900, 1, 1);
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
// If Email Server is enabled
if (config.EmailConfig.Enabled)
{
// 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];
try
{
var account = domain.Accounts.ItemByAddress[email];
throw new Exception("That email already exists.");
}
catch { }
DateTime emailLastActive = UserEmailLastActive(config, user.Username);
if (lastActive < emailLastActive)
lastActive = emailLastActive;

// If we got an exception, then the email doesnt exist and we continue on!
var newAccount = domain.Accounts.Add();
newAccount.Address = email;
newAccount.Password = password;
newAccount.Active = true;
newAccount.MaxSize = config.EmailConfig.MaxSize;
DateTime gitLastActive = UserGitLastActive(config, user.Username);
if (lastActive < gitLastActive)
lastActive = gitLastActive;

newAccount.Save();
}
if (lastActive < user.LastSeen)
lastActive = user.LastSeen;

// If Git is enabled
if (config.GitConfig.Enabled)
{
// Add gogs user
using (var client = new WebClient())
{
var obj = new { source_id = config.GitConfig.SourceId, username = user.Username, email = email, login_name = email, password = password };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/admin/users?token=" + config.GitConfig.AccessToken);
string result = client.UploadString(finalUri, "POST", json);
}
}
return lastActive;
}
catch (Exception ex)
{
throw new Exception("Unable to determine last activity.", ex);
}
}

public static void AddUser(TeknikEntities db, Config config, User user, string password)
{
try
{
// Create an Email Account
AddUserEmail(config, user, password);

// Create a Git Account
AddUserGit(config, user, password);

// Add User
user.HashedPassword = SHA384.Hash(user.Username, password);
db.Users.Add(user);
db.SaveChanges();

@@ -105,195 +119,269 @@ namespace Teknik.Areas.Users.Utility
}
}

public static void SaveUser(TeknikEntities db, Config config, User user, bool changePass, string newPass)
public static void EditUser(TeknikEntities db, Config config, User user, bool changePass, string password)
{
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
// Changing Password?
if (changePass)
try
{
// Update Email Pass
if (config.EmailConfig.Enabled)
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
// Changing Password?
if (changePass)
{
try
{
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[email];
account.Password = newPass;
account.Save();
}
catch (COMException)
{ }
}
// Change email password
EditUserEmailPassword(config, user, password);

// Update Git Pass
if (config.GitConfig.Enabled)
{
using (var client = new WebClient())
{
var obj = new { source_id = config.GitConfig.SourceId, email = email, password = newPass };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/admin/users/" + user.Username + "?token=" + config.GitConfig.AccessToken);
string result = client.UploadString(finalUri, "PATCH", json);
}
// Update Git password
EditUserGitPassword(config, user, password);

// Update User password
user.HashedPassword = SHA384.Hash(user.Username, password);
}
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception ex)
{
throw new Exception("Unable to edit user.", ex);
}
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}

public static void DeleteUser(TeknikEntities db, Config config, User user)
{
// Check to see if we need to delete their email.
if (config.EmailConfig.Enabled)
try
{
try
// Delete Email Account
DeleteUserEmail(config, user);

// Delete Git Account
DeleteUserGit(config, user);

// Update uploads
List<Upload.Models.Upload> uploads = db.Uploads.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (uploads != null)
{
// Delete Email
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain)];
if (account != null)
foreach (Upload.Models.Upload upload in uploads)
{
account.Delete();
upload.UserId = null;
db.Entry(upload).State = EntityState.Modified;
}
}
catch (COMException)

// Update pastes
List<Paste.Models.Paste> pastes = db.Pastes.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (pastes != null)
{
foreach (Paste.Models.Paste paste in pastes)
{
paste.UserId = null;
db.Entry(paste).State = EntityState.Modified;
}
}
catch (Exception ex)

// Update shortened urls
List<ShortenedUrl> shortUrls = db.ShortenedUrls.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (shortUrls != null)
{
throw new Exception("Unable to delete email account.", ex);
foreach (ShortenedUrl shortUrl in shortUrls)
{
shortUrl.UserId = null;
db.Entry(shortUrl).State = EntityState.Modified;
}
}
}

// Delete Git
if (config.GitConfig.Enabled)
{
try
// Delete Blogs
Blog.Models.Blog blog = db.Blogs.Include("BlogPosts").Include("BlogPosts.Comments").Include("User").Where(u => u.User.Username == user.Username).FirstOrDefault();
if (blog != null)
{
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/admin/users/" + user.Username + "?token=" + config.GitConfig.AccessToken);
WebRequest request = WebRequest.Create(finalUri);
request.Method = "DELETE";
db.Blogs.Remove(blog);
}

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.NotFound && response.StatusCode != HttpStatusCode.OK)
// Delete post comments
List<BlogPostComment> postComments = db.BlogComments.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (postComments != null)
{
foreach (BlogPostComment postComment in postComments)
{
throw new Exception("Unable to delete git account. Response Code: " + response.StatusCode);
db.BlogComments.Remove(postComment);
}
}
catch (HttpException htex)
{
if (htex.GetHttpCode() != 404)
throw new Exception("Unable to delete git account. Http Exception: " + htex.Message);
}
catch (Exception ex)

// Delete podcast comments
List<Podcast.Models.PodcastComment> podComments = db.PodcastComments.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (podComments != null)
{
// This error signifies the user doesn't exist, so we can continue deleting
if (ex.Message != "The remote server returned an error: (404) Not Found.")
foreach (Podcast.Models.PodcastComment podComment in podComments)
{
throw new Exception("Unable to delete git account. Exception: " + ex.Message);
db.PodcastComments.Remove(podComment);
}
}

// Delete User
db.Users.Remove(user);
db.SaveChanges();
}
catch (Exception ex)
{
throw new Exception("Unable to delete user.", ex);
}
}
#endregion

// Update uploads
List<Upload.Models.Upload> uploads = db.Uploads.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (uploads != null)
#region Email Management
public static bool UserEmailExists(Config config, string username)
{
// If Email Server is enabled
if (config.EmailConfig.Enabled)
{
foreach (Upload.Models.Upload upload in uploads)
string email = string.Format("{0}@{1}", username, config.EmailConfig.Domain);
// Connect to hmailserver COM
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);

try
{
upload.UserId = null;
db.Entry(upload).State = EntityState.Modified;
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[email];
// We didn't error out, so the email exists
return true;
}
catch { }
}
return false;
}

// Update pastes
List<Paste.Models.Paste> pastes = db.Pastes.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (pastes != null)
public static DateTime UserEmailLastActive(Config config, string username)
{
DateTime lastActive = new DateTime(1900, 1, 1);

if (config.EmailConfig.Enabled)
{
foreach (Paste.Models.Paste paste in pastes)
string email = string.Format("{0}@{1}", username, config.EmailConfig.Domain);
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);

try
{
paste.UserId = null;
db.Entry(paste).State = EntityState.Modified;
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[email];
DateTime lastEmail = (DateTime)account.LastLogonTime;
if (lastActive < lastEmail)
lastActive = lastEmail;
}
catch { }
}
return lastActive;
}

// Update shortened urls
List<ShortenedUrl> shortUrls = db.ShortenedUrls.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (shortUrls != null)
public static void AddUserEmail(Config config, User user, string password)
{
try
{
foreach (ShortenedUrl shortUrl in shortUrls)
// If Email Server is enabled
if (config.EmailConfig.Enabled)
{
shortUrl.UserId = null;
db.Entry(shortUrl).State = EntityState.Modified;
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
// 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 newAccount = domain.Accounts.Add();
newAccount.Address = email;
newAccount.Password = password;
newAccount.Active = true;
newAccount.MaxSize = config.EmailConfig.MaxSize;

newAccount.Save();
}
}

// Delete Blogs
Blog.Models.Blog blog = db.Blogs.Include("BlogPosts").Include("BlogPosts.Comments").Include("User").Where(u => u.User.Username == user.Username).FirstOrDefault();
if (blog != null)
catch (Exception ex)
{
db.Blogs.Remove(blog);
throw new Exception("Unable to add email.", ex);
}
}

// Delete post comments
List<BlogPostComment> postComments = db.BlogComments.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (postComments != null)
public static void EditUserEmailPassword(Config config, User user, string password)
{
try
{
foreach (BlogPostComment postComment in postComments)
// If Email Server is enabled
if (config.EmailConfig.Enabled)
{
db.BlogComments.Remove(postComment);
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[email];
account.Password = password;
account.Save();
}
}
catch (Exception ex)
{
throw new Exception("Unable to edit email account password.", ex);
}
}

// Delete post comments
List<Podcast.Models.PodcastComment> podComments = db.PodcastComments.Include("User").Where(u => u.User.Username == user.Username).ToList();
if (podComments != null)
public static void DeleteUserEmail(Config config, User user)
{
try
{
foreach (Podcast.Models.PodcastComment podComment in podComments)
// If Email Server is enabled
if (config.EmailConfig.Enabled)
{
db.PodcastComments.Remove(podComment);
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain)];
if (account != null)
{
account.Delete();
}
}
}

// Delete User
db.Users.Remove(user);
db.SaveChanges();
catch (Exception ex)
{
throw new Exception("Unable to delete email account.", ex);
}
}
#endregion

public static DateTime GetLastActivity(TeknikEntities db, Config config, User user)
#region Git Management
public static bool UserGitExists(Config config, string username)
{
DateTime lastActive = new DateTime(1900, 1, 1);
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);

if (config.EmailConfig.Enabled)
if (config.GitConfig.Enabled)
{
// Connect to hmailserver COM
var app = new hMailServer.Application();
app.Connect();
app.Authenticate(config.EmailConfig.Username, config.EmailConfig.Password);

try
{
var domain = app.Domains.ItemByName[config.EmailConfig.Domain];
var account = domain.Accounts.ItemByAddress[email];
DateTime lastEmail = (DateTime)account.LastLogonTime;
if (lastActive < lastEmail)
lastActive = lastEmail;
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/users/" + username + "?token=" + config.GitConfig.AccessToken);
WebRequest request = WebRequest.Create(finalUri);
request.Method = "GET";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
return true;
}
}
catch (Exception ex) { }
catch { }
}
return false;
}

public static DateTime UserGitLastActive(Config config, string username)
{
DateTime lastActive = new DateTime(1900, 1, 1);

if (config.GitConfig.Enabled)
{
string email = string.Format("{0}@{1}", username, config.EmailConfig.Domain);
// We need to check the actual git database
MysqlDatabase mySQL = new MysqlDatabase(config.GitConfig.Database);
string sql = @"SELECT MAX(gogs.repository.updated) AS LastUpdate
@@ -310,12 +398,101 @@ namespace Teknik.Areas.Users.Utility
lastActive = tmpLast;
}
}
return lastActive;
}

if (lastActive < user.LastSeen)
lastActive = user.LastSeen;
public static void AddUserGit(Config config, User user, string password)
{
try
{
// If Git is enabled
if (config.GitConfig.Enabled)
{
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
// Add gogs user
using (var client = new WebClient())
{
var obj = new { source_id = config.GitConfig.SourceId, username = user.Username, email = email, login_name = email, password = password };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/admin/users?token=" + config.GitConfig.AccessToken);
string result = client.UploadString(finalUri, "POST", json);
}
}
}
catch (Exception ex)
{
throw new Exception("Unable to add git account.", ex);
}
}

return lastActive;
public static void EditUserGitPassword(Config config, User user, string password)
{
try
{
// If Git is enabled
if (config.GitConfig.Enabled)
{
string email = string.Format("{0}@{1}", user.Username, config.EmailConfig.Domain);
using (var client = new WebClient())
{
var obj = new { source_id = config.GitConfig.SourceId, email = email, password = password };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/admin/users/" + user.Username + "?token=" + config.GitConfig.AccessToken);
string result = client.UploadString(finalUri, "PATCH", json);
}
}
}
catch (Exception ex)
{
throw new Exception("Unable to edit git account password.", ex);
}
}

public static void DeleteUserGit(Config config, User user)
{
try
{
// If Git is enabled
if (config.GitConfig.Enabled)
{
try
{
Uri baseUri = new Uri(config.GitConfig.Host);
Uri finalUri = new Uri(baseUri, "api/v1/admin/users/" + user.Username + "?token=" + config.GitConfig.AccessToken);
WebRequest request = WebRequest.Create(finalUri);
request.Method = "DELETE";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.NotFound && response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Unable to delete git account. Response Code: " + response.StatusCode);
}
}
catch (HttpException htex)
{
if (htex.GetHttpCode() != 404)
throw new Exception("Unable to delete git account. Http Exception: " + htex.Message);
}
catch (Exception ex)
{
// This error signifies the user doesn't exist, so we can continue deleting
if (ex.Message != "The remote server returned an error: (404) Not Found.")
{
throw new Exception("Unable to delete git account. Exception: " + ex.Message);
}
}
}
}
catch (Exception ex)
{
throw new Exception("Unable to delete git account.", ex);
}
}
#endregion

public static HttpCookie CreateAuthCookie(string username, bool remember, string domain, bool local)
{

+ 2
- 0
Teknik/Configuration/UserConfig.cs View File

@@ -10,11 +10,13 @@ namespace Teknik.Configuration
{
public bool RegistrationEnabled { get; set; }
public bool LoginEnabled { get; set; }
public List<string> ReservedUsernames { get; set; }

public UserConfig()
{
RegistrationEnabled = true;
LoginEnabled = true;
ReservedUsernames = new List<string>();
}
}
}

+ 24
- 0
Teknik/Helpers/ExceptionExtensions.cs View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Teknik.Helpers
{
public static class ExceptionExtensions
{
public static string GetFullMessage(this Exception ex, bool recursive = false, bool stackTrace = false)
{
string message = ex.Message;
if (recursive && ex.InnerException != null)
{
message += " | Inner Exception: " + ex.InnerException.GetFullMessage(recursive, stackTrace);
}
if (stackTrace && !string.IsNullOrEmpty(ex.StackTrace))
{
message += " | Stack Trace: " + ex.StackTrace;
}
return message;
}
}
}

+ 1
- 0
Teknik/Teknik.csproj View File

@@ -274,6 +274,7 @@
<Compile Include="Areas\User\Models\PermissionType.cs" />
<Compile Include="Areas\Blog\Models\BlogPost.cs" />
<Compile Include="Areas\User\Models\Role.cs" />
<Compile Include="Helpers\ExceptionExtensions.cs" />
<Compile Include="Helpers\HttpRequestExtensions.cs" />
<Compile Include="Helpers\MysqlDatabase.cs" />
<Compile Include="Helpers\MarkdownHelper.cs" />

Loading…
Cancel
Save