diff --git a/Project-Unite/ACL.cs b/Project-Unite/ACL.cs index ce3bb15..ed22e2a 100644 --- a/Project-Unite/ACL.cs +++ b/Project-Unite/ACL.cs @@ -9,6 +9,8 @@ using System.Web.Mvc.Html; using System.Data.Entity; using System.Text; +using Microsoft.AspNet.Identity.EntityFramework; +using System.Security.Principal; namespace Project_Unite { @@ -226,9 +228,7 @@ public static bool CanSee(string userName, string fId) if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(fId)) return false; - if (!Granted(userName, "CanPostTopics")) - return false; //obviously if this role has a global restraint for this ACL def we shouldn't let them post in ANY forum. - + var db = new ApplicationDbContext(); var usr = db.Users.Include(x => x.Roles).FirstOrDefault(u => u.UserName == userName); @@ -282,7 +282,7 @@ public static bool CanReply(string userName, string fId) if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(fId)) return false; - if (!Granted(userName, "CanPostTopics")) + if (HttpContext.Current.User.Identity.IsGuest()) return false; //obviously if this role has a global restraint for this ACL def we shouldn't let them post in ANY forum. var db = new ApplicationDbContext(); @@ -324,7 +324,7 @@ public static bool CanPost(string userName, string fId) if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(fId)) return false; - if (!Granted(userName, "CanPostTopics")) + if (HttpContext.Current.User.Identity.IsGuest()) return false; //obviously if this role has a global restraint for this ACL def we shouldn't let them post in ANY forum. var db = new ApplicationDbContext(); @@ -389,7 +389,7 @@ public static bool CanManageRole(string userId, string roleId) { try { - if (!Granted(userId, "CanEditRoles")) + if (!HttpContext.Current.User.Identity.IsAdmin()) return false; var db = new ApplicationDbContext(); @@ -425,40 +425,37 @@ public static ForumCategory GetForumById(string id) } - public static bool Granted(string userName, string prop) + public static bool IsGuest(this IIdentity id) { - if (string.IsNullOrWhiteSpace(prop)) - return true; - - try - { - var db = new ApplicationDbContext(); - - var usr = db.Users.FirstOrDefault(u => u.UserName == userName); - - var userRoles = new List(); - foreach (var usrRole in usr.Roles) - { - userRoles.Add(db.Roles.FirstOrDefault(r => r.Id == usrRole.RoleId) as Role); - } - db.Dispose(); - var userRole = userRoles.OrderByDescending(m => m.Priority).First(); - - var t = userRole.GetType(); - foreach (var propInf in t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) - { - if (propInf.Name == prop && propInf.PropertyType == typeof(bool)) - return (bool)propInf.GetValue(userRole); - } - + if (HttpContext.Current.Request.IsAuthenticated) return false; - } - catch (Exception ex) - { - Debug.Print(ex.ToString()); - return false; - } + return true; + } + + public static bool IsModerator(this IIdentity id) + { + var db = new ApplicationDbContext(); + return db.Users.FirstOrDefault(x => x.UserName == id.Name).HighestRole.IsModerator; + } + + public static bool IsDeveloper(this IIdentity id) + { + var db = new ApplicationDbContext(); + return db.Users.FirstOrDefault(x => x.UserName == id.Name).HighestRole.IsDeveloper; + } + + public static bool IsMember(this IIdentity id) + { + var db = new ApplicationDbContext(); + return db.Users.FirstOrDefault(x => x.UserName == id.Name).HighestRole.IsMember; + } + + + public static bool IsAdmin(this IIdentity id) + { + var db = new ApplicationDbContext(); + return db.Users.FirstOrDefault(x => x.UserName == id.Name).HighestRole.IsAdmin; } } } \ No newline at end of file diff --git a/Project-Unite/ACLAttributes.cs b/Project-Unite/ACLAttributes.cs new file mode 100644 index 0000000..a043daf --- /dev/null +++ b/Project-Unite/ACLAttributes.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Project_Unite +{ + /// + /// Tells the Unite request router that this view/action requires administrative permissions. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class RequiresAdmin : Attribute + { + } + + /// + /// Tells the Unite request router that this view/action requires developer permissions. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class RequiresDeveloper : Attribute + { + } + + /// + /// Tells the Unite request router that this view/action requires moderator permissions. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class RequiresModerator : Attribute + { + } + +} \ No newline at end of file diff --git a/Project-Unite/Controllers/AdminController.cs b/Project-Unite/Controllers/AdminController.cs index a0f75c3..cbef219 100644 --- a/Project-Unite/Controllers/AdminController.cs +++ b/Project-Unite/Controllers/AdminController.cs @@ -21,10 +21,9 @@ public class AdminController : Controller private ApplicationDbContext db = new ApplicationDbContext(); [Authorize] + [RequiresAdmin] public ActionResult Index() { - if (!ACL.Granted(User.Identity.Name, "CanAccessAdminCP")) - return new HttpStatusCodeResult(403); return View(); } } diff --git a/Project-Unite/Controllers/BlogController.cs b/Project-Unite/Controllers/BlogController.cs index bc01229..5d964e2 100644 --- a/Project-Unite/Controllers/BlogController.cs +++ b/Project-Unite/Controllers/BlogController.cs @@ -130,12 +130,10 @@ public ActionResult ViewBlog(string id, string comment) return View(blog); } + [RequiresDeveloper] [Authorize] public ActionResult PostBlog() { - if (!ACL.Granted(User.Identity.Name, "CanBlog")) - return new HttpStatusCodeResult(403); - var model = new PostBlogViewModel(); return View(model); } diff --git a/Project-Unite/Controllers/DeveloperController.cs b/Project-Unite/Controllers/DeveloperController.cs index da0022e..cbe1436 100644 --- a/Project-Unite/Controllers/DeveloperController.cs +++ b/Project-Unite/Controllers/DeveloperController.cs @@ -9,23 +9,19 @@ namespace Project_Unite.Controllers { + [RequiresDeveloper] [Authorize] public class DeveloperController : Controller { // GET: Developer public ActionResult Index() { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); ViewBag.Developer = true; return View(); } public ActionResult ToggleObsolete(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var release = db.Downloads.FirstOrDefault(x => x.Id == id); release.Obsolete = !release.Obsolete; @@ -35,9 +31,6 @@ public ActionResult ToggleObsolete(string id) public ActionResult MakeUnstable(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var release = db.Downloads.FirstOrDefault(x => x.Id == id); release.IsStable = false; @@ -48,9 +41,6 @@ public ActionResult MakeUnstable(string id) public ActionResult MakeStable(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var release = db.Downloads.FirstOrDefault(x => x.Id == id); release.IsStable = true; @@ -61,18 +51,12 @@ public ActionResult MakeStable(string id) public ActionResult Releases() { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); var db = new ApplicationDbContext(); return View(db.Downloads); } public ActionResult AddRelease() { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanReleaseBuild")) - return new HttpStatusCodeResult(403); ViewBag.Developer = true; var build = new PostDownloadViewModel(); @@ -85,10 +69,6 @@ public ActionResult AddRelease() [ValidateAntiForgeryToken] public ActionResult AddRelease(PostDownloadViewModel model) { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanReleaseBuild")) - return new HttpStatusCodeResult(403); if (!ModelState.IsValid) return View(model); @@ -174,8 +154,6 @@ public ActionResult AddRelease(PostDownloadViewModel model) [Authorize] public ActionResult Wiki() { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); ViewBag.Developer = true; var db = new ApplicationDbContext(); var cats = db.WikiCategories; @@ -184,9 +162,6 @@ public ActionResult Wiki() public ActionResult AddWikiCategory() { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); - ViewBag.Developer = true; var mdl = new AddWikiCategoryViewModel(); @@ -198,8 +173,6 @@ public ActionResult AddWikiCategory() [ValidateAntiForgeryToken] public ActionResult AddWikiCategory(AddWikiCategoryViewModel model) { - if (!ACL.Granted(User.Identity.Name, "CanAccessDevCP")) - return new HttpStatusCodeResult(403); ViewBag.Developer = true; if (!ModelState.IsValid) return View(model); diff --git a/Project-Unite/Controllers/ForumController.cs b/Project-Unite/Controllers/ForumController.cs index de2174c..3eb3c83 100644 --- a/Project-Unite/Controllers/ForumController.cs +++ b/Project-Unite/Controllers/ForumController.cs @@ -131,16 +131,16 @@ public ActionResult EditPost(string id) string acl_perm = "CanEditPosts"; if (topic == null) return new HttpStatusCodeResult(404); - if (topic.AuthorId == User.Identity.GetUserId()) - acl_perm = "CanEditOwnPosts"; - if (!ACL.Granted(User.Identity.Name, acl_perm)) - return new HttpStatusCodeResult(403); + if (topic.AuthorId != User.Identity.GetUserId()) + if (!User.Identity.IsModerator()) + return new HttpStatusCodeResult(403); var model = new EditPostViewModel(); model.Id = topic.Id; model.Contents = topic.Body; return View(model); } + [RequiresModerator] [Authorize] public ActionResult DeletePost(string id) { @@ -150,10 +150,6 @@ public ActionResult DeletePost(string id) string acl_perm = "CanDeletePosts"; if (topic == null) return new HttpStatusCodeResult(404); - if (topic.AuthorId == User.Identity.GetUserId()) - acl_perm = "CanDeleteOwnPosts"; - if (!ACL.Granted(User.Identity.Name, acl_perm)) - return new HttpStatusCodeResult(403); var parent = db.ForumTopics.FirstOrDefault(x => x.Id == topic.Parent); bool redirectToParent = false; string cat = ""; @@ -184,9 +180,8 @@ public ActionResult EditPost(EditPostViewModel model) string acl_perm = "CanEditPosts"; if (topic == null) return new HttpStatusCodeResult(404); - if (topic.AuthorId == User.Identity.GetUserId()) - acl_perm = "CanEditOwnPosts"; - if (!ACL.Granted(User.Identity.Name, acl_perm)) + if (topic.AuthorId != User.Identity.GetUserId()) + if (!User.Identity.IsModerator()) return new HttpStatusCodeResult(403); var edit = new ForumPostEdit(); edit.EditedAt = DateTime.Now; diff --git a/Project-Unite/Controllers/ModeratorController.cs b/Project-Unite/Controllers/ModeratorController.cs index 7872112..99ef8b7 100644 --- a/Project-Unite/Controllers/ModeratorController.cs +++ b/Project-Unite/Controllers/ModeratorController.cs @@ -9,47 +9,33 @@ namespace Project_Unite.Controllers { + [RequiresModerator] [Authorize] public class ModeratorController : Controller { // GET: Moderator public ActionResult Index() { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - ViewBag.Moderator = true; return View(); } public ActionResult UserDetails(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var usr = db.Users.FirstOrDefault(x => x.DisplayName == id); - if (usr == null || !ACL.Granted(User.Identity.Name, "CanViewUserInfo")) - return new HttpStatusCodeResult(403); + if (usr == null) + return new HttpStatusCodeResult(404); return View(usr); } public ActionResult Users() { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanViewUserInfo")) - return new HttpStatusCodeResult(403); - return View(new ApplicationDbContext().Users); } public ActionResult Unban(string id, string returnUrl = "") { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanIssueBan")) - return new HttpStatusCodeResult(403); var db = new ApplicationDbContext(); var usr = db.Users.FirstOrDefault(x => x.Id == id); @@ -73,10 +59,6 @@ public ActionResult Unban(string id, string returnUrl = "") public ActionResult Ban(string id, string returnUrl = "") { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanIssueBan")) - return new HttpStatusCodeResult(403); var db = new ApplicationDbContext(); var usr = db.Users.FirstOrDefault(x => x.Id == id); @@ -102,10 +84,6 @@ public ActionResult Ban(string id, string returnUrl = "") public ActionResult Unmute(string id, string returnUrl = "") { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanIssueMute")) - return new HttpStatusCodeResult(403); var db = new ApplicationDbContext(); var usr = db.Users.FirstOrDefault(x => x.Id == id); @@ -130,13 +108,6 @@ public ActionResult Unmute(string id, string returnUrl = "") [ValidateAntiForgeryToken] public ActionResult ChangeUserName(string id, ApplicationUser model, string returnUrl = "") { - string acl_r = "CanEditUsernames"; - if (id == User.Identity.GetUserId()) - acl_r = "CanEditUsername"; - - if (!ACL.Granted(User.Identity.Name, acl_r)) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var usr = db.Users.FirstOrDefault(x => x.Id == id); if (usr == null) @@ -155,20 +126,12 @@ public ActionResult ChangeUserName(string id, ApplicationUser model, string retu public ActionResult Lock(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var forum = db.ForumTopics.FirstOrDefault(x => x.Discriminator == id); if (forum == null) return new HttpStatusCodeResult(404); string perm = "CanLockTopics"; var uid = User.Identity.GetUserId(); - if (forum.AuthorId == uid) - perm = "CanLockOwnTopics"; - - if (!ACL.Granted(User.Identity.Name, perm)) - return new HttpStatusCodeResult(403); if (forum.IsLocked == true) //Save the DB queries... return new HttpStatusCodeResult(HttpStatusCode.BadRequest); @@ -183,20 +146,12 @@ public ActionResult Lock(string id) public ActionResult Unlock(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var forum = db.ForumTopics.FirstOrDefault(x => x.Discriminator == id); if (forum == null) return new HttpStatusCodeResult(404); string perm = "CanUnlockTopics"; var uid = User.Identity.GetUserId(); - if (forum.AuthorId == uid) - perm = "CanUnlockOwnTopics"; - - if (!ACL.Granted(User.Identity.Name, perm)) - return new HttpStatusCodeResult(403); if (forum.IsLocked == false) //Save the DB queries... return new HttpStatusCodeResult(HttpStatusCode.BadRequest); @@ -212,20 +167,12 @@ public ActionResult Unlock(string id) public ActionResult List(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var forum = db.ForumTopics.FirstOrDefault(x => x.Discriminator == id); if (forum == null) return new HttpStatusCodeResult(404); string perm = "CanUnlistTopics"; var uid = User.Identity.GetUserId(); - if (forum.AuthorId == uid) - perm = "CanUnlistOwnTopics"; - - if (!ACL.Granted(User.Identity.Name, perm)) - return new HttpStatusCodeResult(403); if (forum.IsUnlisted == false) //Save the DB queries... return new HttpStatusCodeResult(HttpStatusCode.BadRequest); @@ -240,20 +187,12 @@ public ActionResult List(string id) public ActionResult Unlist(string id) { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); var forum = db.ForumTopics.FirstOrDefault(x => x.Discriminator == id); if (forum == null) return new HttpStatusCodeResult(404); string perm = "CanUnlistTopics"; var uid = User.Identity.GetUserId(); - if (forum.AuthorId == uid) - perm = "CanUnlistOwnTopics"; - - if (!ACL.Granted(User.Identity.Name, perm)) - return new HttpStatusCodeResult(403); if (forum.IsUnlisted == true) //Save the DB queries... return new HttpStatusCodeResult(HttpStatusCode.BadRequest); @@ -280,9 +219,6 @@ public ActionResult Bans() public ActionResult Logs() { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - var db = new ApplicationDbContext(); return View(db.AuditLogs.Where(x => x.Level != AuditLogLevel.Admin)); @@ -290,10 +226,6 @@ public ActionResult Logs() public ActionResult Mute(string id, string returnUrl = "") { - if (!ACL.Granted(User.Identity.Name, "CanAccessModCP")) - return new HttpStatusCodeResult(403); - if (!ACL.Granted(User.Identity.Name, "CanIssueMute")) - return new HttpStatusCodeResult(403); var db = new ApplicationDbContext(); var usr = db.Users.FirstOrDefault(x => x.Id == id); diff --git a/Project-Unite/Global.asax.cs b/Project-Unite/Global.asax.cs index 10223f1..569bd17 100644 --- a/Project-Unite/Global.asax.cs +++ b/Project-Unite/Global.asax.cs @@ -3,6 +3,7 @@ using System.Data.Entity.Migrations; using System.IO; using System.Linq; +using System.Reflection; using System.Web; using System.Web.Mvc; using System.Web.Optimization; @@ -36,6 +37,44 @@ protected void Application_BeginRequest(object sender, EventArgs e) migrator.Update(); + string actionname = this.Request.RequestContext.RouteData.Values["action"].ToString(); + string controllername = this.Request.RequestContext.RouteData.Values["controller"].ToString(); + + var asm = Assembly.GetExecutingAssembly(); + var ctl = asm.GetTypes().FirstOrDefault(x => x.Name == controllername + "Controller"); + var adm = ctl.GetCustomAttributes(false).Where(x => x is RequiresAdmin); + var mod = ctl.GetCustomAttributes(false).Where(x => x is RequiresModerator); + var dev = ctl.GetCustomAttributes(false).Where(x => x is RequiresDeveloper); + + bool fail = false; + + if (adm != null) + fail = !User.Identity.IsAdmin(); + if (mod != null) + fail = !User.Identity.IsModerator(); + if (dev != null) + fail = !User.Identity.IsDeveloper(); + + var act = ctl.GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(x => x.Name == actionname); + + adm = act.GetCustomAttributes(false).Where(x => x is RequiresAdmin); + mod = act.GetCustomAttributes(false).Where(x => x is RequiresModerator); + dev = act.GetCustomAttributes(false).Where(x => x is RequiresDeveloper); + + if (adm != null) + fail = fail || !User.Identity.IsAdmin(); + if (mod != null) + fail = fail || !User.Identity.IsModerator(); + if (dev != null) + fail = fail || !User.Identity.IsDeveloper(); + + + if (fail == true) + { + string url = "http://" + this.Request.Url.Host.Replace("http://", "").Replace("https://", "") + "/Home/AccessDenied"; + Response.Redirect(url, true); + return; + } var addr = HttpContext.Current.Request.UserHostAddress; var db = new ApplicationDbContext(); @@ -47,6 +86,8 @@ protected void Application_BeginRequest(object sender, EventArgs e) this.CompleteRequest(); return; } + + } protected void Application_EndRequest(object s, EventArgs e) diff --git a/Project-Unite/Project-Unite.csproj b/Project-Unite/Project-Unite.csproj index f4da41b..7224e30 100644 --- a/Project-Unite/Project-Unite.csproj +++ b/Project-Unite/Project-Unite.csproj @@ -243,6 +243,7 @@ + diff --git a/Project-Unite/Views/Shared/_Layout.cshtml b/Project-Unite/Views/Shared/_Layout.cshtml index 5ade38b..8c21f1c 100644 --- a/Project-Unite/Views/Shared/_Layout.cshtml +++ b/Project-Unite/Views/Shared/_Layout.cshtml @@ -97,9 +97,9 @@ }
-
+
-

Welcome to Project: Unite! Things are a bit barren right now and not a lot of stuff is implemented - but feel free to explore!

+

Do things seem broken? We are currently working on streamlining the permission system and its backend. Please be patient!

@@ -112,84 +112,8 @@
} - @if (ViewBag.Moderator == true) - { - - @RenderBody(); - } - else if (ViewBag.Developer == true) - { - - - - @RenderBody(); - } - else if (ACL.Granted(User.Identity.Name, ViewBag.ACLRule)) - { - if (ViewBag.Admin == true) - { - if (ACL.Granted(User.Identity.Name, "CanAccessAdminCP")) - { - - - - @RenderBody(); - } - else - { -

Access denied.

-

You do not have permission to access this page. Contact an admin if this is in error.

- } - } - else - { - - @RenderBody() - - } - } - else - { -

Access denied.

-

You do not have permission to access this page. Contact an admin if this is in error.

- - }
+ @RenderBody() +
@@ -232,7 +156,7 @@

We'd like to formally thank Philip Adams. Without him, we would not exist. Phil has contributed years of work and help to ShiftOS and is the original developer of the game. He has written code that is still used to this day in modern ShiftOS, and much of the ideas and mechanics in the game are from his mind.

Check Phil out on YouTube: OSFirstTimer | AstralPhaser | YouTube Millionaire

- @if (ACL.Granted(User.Identity.Name, "CanAccessAdminCP")) + @if (User.Identity.IsAdmin()) {

@Html.ActionLink("Administrator Control Panel", "Index", "Admin")

}