{"id":17244126,"url":"https://github.com/mcintyre321/harden","last_synced_at":"2025-10-06T02:57:01.456Z","repository":{"id":1632373,"uuid":"2355751","full_name":"mcintyre321/Harden","owner":"mcintyre321","description":"Harden your .NET objects with dynamic access controls. Tie domain behaviour to objects not classes!","archived":false,"fork":false,"pushed_at":"2016-05-28T12:21:59.000Z","size":2429,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-21T04:30:05.109Z","etag":null,"topics":["c-sharp","csharp","ddd","validation"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcintyre321.png","metadata":{"files":{"readme":"README.markdown","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-09-09T14:06:22.000Z","updated_at":"2024-05-20T00:51:45.000Z","dependencies_parsed_at":"2022-07-18T22:19:10.390Z","dependency_job_id":null,"html_url":"https://github.com/mcintyre321/Harden","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mcintyre321/Harden","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcintyre321%2FHarden","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcintyre321%2FHarden/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcintyre321%2FHarden/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcintyre321%2FHarden/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcintyre321","download_url":"https://codeload.github.com/mcintyre321/Harden/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcintyre321%2FHarden/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278551483,"owners_count":26005389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","csharp","ddd","validation"],"created_at":"2024-10-15T06:17:50.343Z","updated_at":"2025-10-06T02:57:01.423Z","avatar_url":"https://github.com/mcintyre321.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"HARDEN\n======\n\nFor .NET\n\nYour domain model is weak. It's a pansy. It needs to be *Hardened*.\n\nHarden takes your objects and wraps them in a super hard layer, preventing code from being called when it's not meant to be called, in ways it's not meant to be called.\n\nHeres an example of a class ready to be hardened:\n\n    public class User\n    {\n        public virtual void Ban() { ... } //virtual so we can proxy it\n\n        public bool AllowBan()\n        {\n            return Context.CurrentUser.IsAdmin; //only admins can Ban users\n        }\n        \n        public virtual string Email { get; set; }\n\n        public bool AllowEmail()\n        {\n            return Context.CurrentUser.IsAdmin || Context.CurrentUser == this;\n            //only admins can see or change other peoples emails\n        }                \n    }\n\nNow we harden it:\n\n    var user = Hardener.Harden(user);\n    user.Ban; //You better be an admin, or you just got yourself a HardenException\n\n\nThe Why\n-------\n\nSome of you might be asking why you need this. After all, the only people who can access against your model are you and other developers at your company...\n\nSTOP. RIGHT. THERE.\n\nLike it or not, objects end up with internal state machines, with methods that should be called in certain ways.\nWhether it's someone else at your company, someone who used to work there or someone who will, at some point your objects are going to be misused, maltreated \n\nand a new bug is going to have to be found and raised and fixed. Invalid calls to Hardened objects don't make it into the trunk.\n\nOf course, you don't need Harden to harden an object, but it helps.\n\n\nValidation\n----------\n\nOH yeah it validates method parameters too, so your\n\n    public virtual void DoSomething(DateTime a, DateTime b, string c, int d){ ... }\n    public IEnumerable\u003cError\u003e ValidateDoSomething(DateTime a, DateTime b, string c) //d omitted as it doesn't need validation\n    {\n        if (a \u003e b) yield return new Error(\"a\", \"First date must be on or before second\");\n        if (c.IsRudeWord()) yield return new Error(\"c\", \"Naughty naughty!\");\n    }\n\n\nand properties\n\n    public virtual string Name { get; set; }\n    public IEnumerable\u003cError\u003e ValidateName(string value)\n    {\n        if (string.IsNullOrEmpty(value)) yield return new Error(\"c\", \"Name must be entered\");\n        if ((value ?? \"\").Length \u003c 4) yield return new Error(\"c\", \"A REAL name must be entered!\");      \n    }\n\nCall with bad data and you get a single ValidationException with all the errors in it.\n\nSyntax\n------\n\nPretty simple, AllowX methods must return bool? (null means that this method isn't sure whether to allow or deny), ValidateX methods return IEnumerable\u003cError\u003e\n\nIf you only want to do a property getter or setter, you can write AllowGetX or AllowSetY\n\nIf you want to put an allow method for all properties, you can write:\n\n\u003e public bool? Allow(MethodInfo calledMethodInfo)\n\n\n\nTo install Harden use the nuget browser or from the package manager console in VS:    \n    \n    PM\u003e Install-Package Harden\n    \nAdvanced usage\n--------------\n\nI hooked the HardenInterceptor up to my IOC container, now all my entities as as hard as nails. I hardened my API, and now I don't worry about script kiddies screwing with Joe Public's data.\n    \nRemember HARD CODE IS GOOD CODE\n    \n\n\n[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/mcintyre321/harden/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcintyre321%2Fharden","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcintyre321%2Fharden","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcintyre321%2Fharden/lists"}