{"id":16024442,"url":"https://github.com/freyskeyd/authorized","last_synced_at":"2025-06-14T01:38:26.298Z","repository":{"id":70792801,"uuid":"233025629","full_name":"Freyskeyd/authorized","owner":"Freyskeyd","description":"Struct authorization by scopes checking","archived":false,"fork":false,"pushed_at":"2020-04-12T20:33:41.000Z","size":27,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-12T14:12:06.274Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","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/Freyskeyd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-10T10:40:51.000Z","updated_at":"2020-06-23T10:36:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"917113d3-7c9a-4cba-b3cf-7f498c3586b0","html_url":"https://github.com/Freyskeyd/authorized","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freyskeyd%2Fauthorized","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freyskeyd%2Fauthorized/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freyskeyd%2Fauthorized/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Freyskeyd%2Fauthorized/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Freyskeyd","download_url":"https://codeload.github.com/Freyskeyd/authorized/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241444196,"owners_count":19963760,"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","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":[],"created_at":"2024-10-08T19:20:39.675Z","updated_at":"2025-03-02T01:17:38.885Z","avatar_url":"https://github.com/Freyskeyd.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Authorized\n\nAuthorized allows you to prevent leaking informations on your structs based on scopes.\nImagine a system which have users, some are admins, others are regular users. You don't want regular users to see\neveryones email so you need to filter every users structs to remove or clean every email based on the current user. Authorized allow you to easly define scope on each fields of the user struct preventing data leak.\n\nScope are composed of keywords defining behaviour for your application. These scopes are used to filter and authorized\nstruct instance.\n\nSee more in usage part.\n\nOther things to include:\n\n  - **Status**:  Alpha. See [CHANGELOG](CHANGELOG.md) for more informations.\n  - **Documentation**:  See [docs.rs](CHANGELOG.md).\n\n## Dependencies\n\nThis crate have no dependencies for the `default` feature.\nBut a `serde` feature is available to have a nice compatibility with `serde` allowing you to serialize structs with every authorized rules defined.\n\n## Installation\n\nSimply add the authorized crate to your dependencies.\n\n```toml\n[dependencies]\nauthorized = \"0.1\"\n```\n\nYou can also define the `serde` feature if you want to have the `serde` integration.\n\n```toml\n[dependencies]\nauthorized = { version = \"0.1\", features = [\"with_serde\"] }\n```\n\n## Configuration\n\nAuthorized is mostly derive based, you can use it without derive but it can be really verbosed.\n\nHere's how to configure a user struct that filter the email for every non admin scope.\n\n```rust\nuse authorized::prelude::*;\n\n#[derive(Authorized)]\nstruct User {\n  id: i32,\n  username: String,\n  #[authorized(scope = \"admin\")]\n  email: String,\n}\n```\n\n## Usage\n\nAuthorized can be use with any sort of application (api, worker, ...). The basic\nconcept is to define scopes for entities (or fields inside entities) and make an\nassessment between an input scope which can be a user one.\n\nAs an example we will use an API which exposes users to authenticated API users.\nWe will not cover the authentication process which is completely out of scope\nbut we will assume that the authentication provides enough informations to build\na `Scope`.\n\nOur Authentication process can handle three kind of role:\n\n- `Guest` which is an unauthenticated API user without any access\n- `AuthenticatedUser` which is a normal user\n- `Admin` which is a super user with extended permissions and access\n\n\nOur API will expose `User` which is composed with an `id`, an `email`, a `name`\nand a `password`. We will define rules on the `User` to restrict access to\ninformations.\n\nRules are:\n\n- `id` and `name` can be seen by `AuthenticatedUser` and `Admin`\n- `email` can be seen by `Admin`\n- `Guest` are not authorized to request this structure\n\n```rust\n#[derive(Authorized)]\n#[authorized(scope = \"read:user\")]\nstruct User {\n  id: i32,\n  name: String,\n  #[authorized(scope = \"read:user:email\")]\n  email: String\n}\n```\n\nAs you can see we can define scope for the global structure and for particular\nfields.\n\nNext we can authorize this structure against any scope:\n\n```rust\nfn main() {\n  let user = User {\n    id: 1,\n    name: \"some_name\".into(),\n    email: \"some_email\".into()\n  };\n\n  let guest = \"guest\"\n  let authorizedUser = \"read:user\"\n  let admin = \"read:user read:user:email\"\n\n  let authorized_guest: AuthorizedResult\u003cUser\u003e = Authorizor::authorize(\u0026user, guest);\n  let authorized_user: AuthorizedResult\u003cUser\u003e = Authorizor::authorize(\u0026user, authauthorizedUser);\n  let authorized_admin: AuthorizedResult\u003cUser\u003e = Authorizor::authorize(\u0026user, admin);\n\n  assert(authorized_guest.status == AuthorizationStatus::UnAuthorized);\n  assert(authorized_user.status == AuthorizationStatus::Authorized);\n  assert(authorized_admin.status == AuthorizationStatus::Authorized);\n\n  assert(authorized_user.inner.email == \"\");\n  assert(authorized_admin.inner.email == \"some_email\");\n\n  assert(authorized_user.unauthorized_fields == vec![\"email\"]);\n  assert(authorized_admin.unauthorized_fields == vec![]);\n}\n```\n\nMore examples can be found in the examples directory.\n\n\n## How to test the software\n\nTo test the software you just need to run `cargo test` inside each crate.\n\n## Known issues\n\n- Authorized doesn't allow multiple global scope or multiple scope for a field.\n\n## Getting help\n\nIf you have questions, concerns, bug reports, etc, please file an issue in this repository's Issue Tracker.\n\n## Getting involved\n\nGeneral instructions on _how_ to contribute should be stated with a link to [CONTRIBUTING](CONTRIBUTING.md).\n\n\n----\n\n## Open source licensing info\n1. [TERMS](TERMS.md)\n2. [LICENSE](LICENSE)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreyskeyd%2Fauthorized","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreyskeyd%2Fauthorized","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreyskeyd%2Fauthorized/lists"}