diff --git a/ServerMaint/Program.cs b/ServerMaint/Program.cs index e2dc3a3..e3d0b8d 100644 --- a/ServerMaint/Program.cs +++ b/ServerMaint/Program.cs @@ -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 { msg }); Output(msg); } @@ -166,6 +166,13 @@ namespace ServerMaint List 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 diff --git a/Teknik/Areas/User/Controllers/UserController.cs b/Teknik/Areas/User/Controllers/UserController.cs index 0f900f4..3fdb516 100644 --- a/Teknik/Areas/User/Controllers/UserController.cs +++ b/Teknik/Areas/User/Controllers/UserController.cs @@ -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); + 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) + { + model.Email = string.Format("{0}@{1}", user.Username, Config.EmailConfig.Domain); + } + model.JoinDate = user.JoinDate; + model.LastSeen = UserHelper.GetLastActivity(db, Config, user); + + model.UserSettings = user.UserSettings; + model.BlogSettings = user.BlogSettings; + model.UploadSettings = user.UploadSettings; + + model.Uploads = db.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList(); + + model.Pastes = db.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList(); + + model.ShortenedUrls = db.ShortenedUrls.Where(s => s.UserId == user.UserId).OrderByDescending(s => s.DateAdded).ToList(); + + return View(model); } - model.JoinDate = user.JoinDate; - model.LastSeen = UserHelper.GetLastActivity(db, Config, user); - - model.UserSettings = user.UserSettings; - model.BlogSettings = user.BlogSettings; - model.UploadSettings = user.UploadSettings; - - model.Uploads = db.Uploads.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DateUploaded).ToList(); - - model.Pastes = db.Pastes.Where(u => u.UserId == user.UserId).OrderByDescending(u => u.DatePosted).ToList(); - - 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; + + user.UserSettings.Website = website; + user.UserSettings.Quote = quote; + user.UserSettings.About = about; + + user.BlogSettings.Title = blogTitle; + user.BlogSettings.Description = blogDesc; + + user.UploadSettings.SaveKey = saveKey; + user.UploadSettings.ServerSideEncrypt = serverSideEncrypt; + UserHelper.EditUser(db, Config, user, changePass, newPass); + return Json(new { result = true }); } - - // 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.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 }); + 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); + try + { + UserHelper.DeleteUser(db, Config, user); + } + catch (Exception ex) + { + return Json(new { error = ex.Message }); + } + // Sign Out + Logout(); + return Json(new { result = true }); } - catch (Exception ex) - { - return Json(new { error = ex.Message }); - } - // 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" }); diff --git a/Teknik/Areas/User/Utility/UserHelper.cs b/Teknik/Areas/User/Utility/UserHelper.cs index 68d9b2e..2a8ec41 100644 --- a/Teknik/Areas/User/Utility/UserHelper.cs +++ b/Teknik/Areas/User/Utility/UserHelper.cs @@ -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 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); + + DateTime emailLastActive = UserEmailLastActive(config, user.Username); + if (lastActive < emailLastActive) + lastActive = emailLastActive; + + DateTime gitLastActive = UserGitLastActive(config, user.Username); + if (lastActive < gitLastActive) + lastActive = gitLastActive; + + if (lastActive < user.LastSeen) + lastActive = user.LastSeen; + + 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 { - 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); + // Create an Email Account + AddUserEmail(config, user, password); - var domain = app.Domains.ItemByName[config.EmailConfig.Domain]; - try - { - var account = domain.Accounts.ItemByAddress[email]; - throw new Exception("That email already exists."); - } - catch { } - - // 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; - - newAccount.Save(); - } - - // 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); - } - } + // Create a Git Account + AddUserGit(config, user, password); // Add User + user.HashedPassword = SHA384.Hash(user.Username, password); db.Users.Add(user); db.SaveChanges(); @@ -105,178 +119,144 @@ 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. + try + { + // Delete Email Account + DeleteUserEmail(config, user); + + // Delete Git Account + DeleteUserGit(config, user); + + // Update uploads + List uploads = db.Uploads.Include("User").Where(u => u.User.Username == user.Username).ToList(); + if (uploads != null) + { + foreach (Upload.Models.Upload upload in uploads) + { + upload.UserId = null; + db.Entry(upload).State = EntityState.Modified; + } + } + + // Update pastes + List 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; + } + } + + // Update shortened urls + List shortUrls = db.ShortenedUrls.Include("User").Where(u => u.User.Username == user.Username).ToList(); + if (shortUrls != null) + { + foreach (ShortenedUrl shortUrl in shortUrls) + { + shortUrl.UserId = null; + db.Entry(shortUrl).State = EntityState.Modified; + } + } + + // 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) + { + db.Blogs.Remove(blog); + } + + // Delete post comments + List postComments = db.BlogComments.Include("User").Where(u => u.User.Username == user.Username).ToList(); + if (postComments != null) + { + foreach (BlogPostComment postComment in postComments) + { + db.BlogComments.Remove(postComment); + } + } + + // Delete podcast comments + List podComments = db.PodcastComments.Include("User").Where(u => u.User.Username == user.Username).ToList(); + if (podComments != null) + { + foreach (Podcast.Models.PodcastComment podComment in podComments) + { + db.PodcastComments.Remove(podComment); + } + } + + // Delete User + db.Users.Remove(user); + db.SaveChanges(); + } + catch (Exception ex) + { + throw new Exception("Unable to delete user.", ex); + } + } + #endregion + + #region Email Management + public static bool UserEmailExists(Config config, string username) + { + // If Email Server is enabled if (config.EmailConfig.Enabled) { + 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 { - // 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) - { - account.Delete(); - } - } - catch (COMException) - { - } - catch (Exception ex) - { - throw new Exception("Unable to delete email account.", ex); + var account = domain.Accounts.ItemByAddress[email]; + // We didn't error out, so the email exists + return true; } + catch { } } - - // Delete Git - 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); - } - } - } - - // Update uploads - List uploads = db.Uploads.Include("User").Where(u => u.User.Username == user.Username).ToList(); - if (uploads != null) - { - foreach (Upload.Models.Upload upload in uploads) - { - upload.UserId = null; - db.Entry(upload).State = EntityState.Modified; - } - } - - // Update pastes - List 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; - } - } - - // Update shortened urls - List shortUrls = db.ShortenedUrls.Include("User").Where(u => u.User.Username == user.Username).ToList(); - if (shortUrls != null) - { - foreach (ShortenedUrl shortUrl in shortUrls) - { - shortUrl.UserId = null; - db.Entry(shortUrl).State = EntityState.Modified; - } - } - - // 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) - { - db.Blogs.Remove(blog); - } - - // Delete post comments - List postComments = db.BlogComments.Include("User").Where(u => u.User.Username == user.Username).ToList(); - if (postComments != null) - { - foreach (BlogPostComment postComment in postComments) - { - db.BlogComments.Remove(postComment); - } - } - - // Delete post comments - List podComments = db.PodcastComments.Include("User").Where(u => u.User.Username == user.Username).ToList(); - if (podComments != null) - { - foreach (Podcast.Models.PodcastComment podComment in podComments) - { - db.PodcastComments.Remove(podComment); - } - } - - // Delete User - db.Users.Remove(user); - db.SaveChanges(); + return false; } - public static DateTime GetLastActivity(TeknikEntities db, Config config, User user) + public static DateTime UserEmailLastActive(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) { - // Connect to hmailserver COM + 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); @@ -289,11 +269,119 @@ namespace Teknik.Areas.Users.Utility if (lastActive < lastEmail) lastActive = lastEmail; } - catch (Exception ex) { } + catch { } } - + return lastActive; + } + + public static void AddUserEmail(Config config, User user, string password) + { + try + { + // If Email Server is enabled + if (config.EmailConfig.Enabled) + { + 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(); + } + } + catch (Exception ex) + { + throw new Exception("Unable to add email.", ex); + } + } + + public static void EditUserEmailPassword(Config config, User user, string password) + { + try + { + // If Email Server is enabled + if (config.EmailConfig.Enabled) + { + 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); + } + } + + public static void DeleteUserEmail(Config config, User user) + { + try + { + // If Email Server is enabled + if (config.EmailConfig.Enabled) + { + 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(); + } + } + } + catch (Exception ex) + { + throw new Exception("Unable to delete email account.", ex); + } + } + #endregion + + #region Git Management + public static bool UserGitExists(Config config, string username) + { if (config.GitConfig.Enabled) { + try + { + 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 { } + } + 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,13 +398,102 @@ namespace Teknik.Areas.Users.Utility lastActive = tmpLast; } } - - if (lastActive < user.LastSeen) - lastActive = user.LastSeen; - return lastActive; } + 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); + } + } + + 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) { Config config = Config.Load(); diff --git a/Teknik/Configuration/UserConfig.cs b/Teknik/Configuration/UserConfig.cs index f0f047b..7989876 100644 --- a/Teknik/Configuration/UserConfig.cs +++ b/Teknik/Configuration/UserConfig.cs @@ -10,11 +10,13 @@ namespace Teknik.Configuration { public bool RegistrationEnabled { get; set; } public bool LoginEnabled { get; set; } + public List ReservedUsernames { get; set; } public UserConfig() { RegistrationEnabled = true; LoginEnabled = true; + ReservedUsernames = new List(); } } } diff --git a/Teknik/Helpers/ExceptionExtensions.cs b/Teknik/Helpers/ExceptionExtensions.cs new file mode 100644 index 0000000..f93cfaa --- /dev/null +++ b/Teknik/Helpers/ExceptionExtensions.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/Teknik/Teknik.csproj b/Teknik/Teknik.csproj index a26e0c1..4bfdaf6 100644 --- a/Teknik/Teknik.csproj +++ b/Teknik/Teknik.csproj @@ -274,6 +274,7 @@ +