{"id":21101177,"url":"https://github.com/brentgreeff/fat_model_auth","last_synced_at":"2025-11-11T19:13:22.019Z","repository":{"id":735252,"uuid":"385171","full_name":"brentgreeff/fat_model_auth","owner":"brentgreeff","description":"Simple clean Authorization system for Rails","archived":false,"fork":false,"pushed_at":"2022-12-14T14:57:02.000Z","size":65,"stargazers_count":3,"open_issues_count":4,"forks_count":3,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-15T05:06:01.938Z","etag":null,"topics":["authorization","rails","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/brentgreeff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2009-11-25T13:08:14.000Z","updated_at":"2022-08-05T17:18:45.000Z","dependencies_parsed_at":"2023-01-13T10:38:45.090Z","dependency_job_id":null,"html_url":"https://github.com/brentgreeff/fat_model_auth","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentgreeff%2Ffat_model_auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentgreeff%2Ffat_model_auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentgreeff%2Ffat_model_auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brentgreeff%2Ffat_model_auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brentgreeff","download_url":"https://codeload.github.com/brentgreeff/fat_model_auth/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225444760,"owners_count":17475353,"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":["authorization","rails","ruby"],"created_at":"2024-11-19T23:41:18.915Z","updated_at":"2025-11-11T19:13:16.995Z","avatar_url":"https://github.com/brentgreeff.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://semaphoreci.com/api/v1/brentgreeff/fat_model_auth/branches/master/badge.svg)](https://semaphoreci.com/brentgreeff/fat_model_auth)\n\n- [Example app - view installation diff](https://github.com/brentgreeff/basic_rails_5_api/commit/6f0cedff4077c1609d32567bfb889fc8fa908db7)\n\n# FatModelAuth\n\nWikipedia defines Authorization as:\n\n\u003e “the function of specifying access rights to resources”\n\nFat Model Auth allows the resources themselves to define these rights.\n\n## Install\n\nAdd to Gemfile\n\n    $ gem fat_model_auth\n\n## Fat Model Auth is a simple, clean authorization system for Rails\n\nHow simple?\n\n## ArticlesController\n\n```\nbefore_action :load_article\n\ndef edit\nend\n\ndef update\nend\n\nprivate\n\ndef load_article\n  Article.find(params[:id])\nend\n```\n\nWe want to ensure only the Article's author can view the edit page or update the article.\n\n### Add a before filter to the articles_controller:\n\n`before_action :auth_required, only: [:edit, :update]`\n\nSince this is the article controller, the resource in question is the @article.\n\nauth_required must be called after the resource is already loaded.\n\nLike this:\n\n```\nbefore_action :load_article, only: [:edit, :update]\nbefore_action :auth_required, only: [:edit, :update]\n```\n\nauth_required will infer the name of the resource from the controller. In the case of articles_controller, it will look for an @article instance variable.\n\nTry and view the articles#edit page from a browser, or event better: re-run the spec.\n\nYou should get an exception:\n\n`undefined method 'allows' for #\u003cArticle:0x204a8d8\u003e`\n\nThis means the gem is working correctly.\n\nfat_model_auth has generated a call to the @article model:\n\n`@article.allows(current_user).to_edit?`\n\nYou need to define a `current_user` method in the application_controller, so that the current user is passed in for evaluation.\n\nIf `current_user` is `nil`, the controller will always return access_denied.\n\n\n## In the Article Model\n\n* Add the following:\n\n```\nallows :edit, :update,\n  if: -\u003e (article, user) { article.author == user }\n```\n\nThe article model now supports the allows instance method, with 2 chains:\n\n`@article.allows(current_user).to_edit?`\n\n- called from the #edit action when using the auth_required before_action.\n\n`@article.allows(current_user).to_update?`\n\n- called on the update action.\n\n### Access Denied is 404\n\nTrying to access a resource without permission returns 404.\n\nBy returning 403 (Forbidden) you might be revealing potentially sensitive information.\n\n404 = that doesn't exist.\n\n403 = Yes that does exist, but you need to try harder to get access to it.\n\n\n### New \u0026 Create\n\nWhen dealing with the #new \u0026 #create actions we need a slightly different approach.\n\nQuite often we will build the new object in the action.\n\n```\ndef create\n  @article = current_user.articles.build(params[:article])\n  return if access_denied?\nend\n```\n\nWhen you call access_denied? fat_model_auth will ask the @article if access is allowed.\n\nThe following call is generated for you:\n\n`@article.allows(current_user).to_create?`\n\n\n### What if you need different rules for different actions?\n\n```\nallows :edit,\n  if: -\u003e (article, user) { article.author.can_edit? }\n\nallows :update,\n  if: -\u003e (article, user) { article.allows_updating? }\n\nallows :delete,\n  unless: -\u003e (article, user) { user.can_delete?(article) }\n```\n\nBoth if: and unless: symbols are supported.\n\n\n### What if you are loading an @article in the StoriesController\n\nWe need to tell the controller which object will act as the authority.\n\n      class StoriesController \u003c ApplicationController\n        def override_authority\n          @article\n        end\n      end\n\n\n## View (templates)\n\nControl which links, buttons or controls are displayed to a user:\n\n`\u003c%= link_to('EDIT', edit_article_path(article)) if allowed_to? edit: article -%\u003e`\n\n\nControl which blocks of html are accessible:\n\n```\n\u003c% if allowed_to? edit_or_destroy: article -%\u003e\n  \u003cfunky\u003ehtml\u003c/funky\u003e\n\u003c% end %\u003e\n```\n\n\n## Test First\n\nBefore adding unit tests, its best to start with a request_spec or another kind of integration test which is focussed on user interaction.\n\nIf the integration test covers the logic in the model then that might be sufficient.\n\n## Request specs\n```\nlogin_as no_good_user\n\nget \"/articles/#{article.to_param}/edit\"\n\nexpect( response ).to have_http_status(404)\n```\n\nIf you are using a mock user, you can stub the response\n\n```\nlet(:yes) { FatModelAuth::CannedGateKeeper.allows(:edit) }\n\nit \"allows\"\n  expect(article).to receive(:allows).and_return(yes)\nend\n```\n\nor\n\n```\nlet(:no) { FatModelAuth::CannedGateKeeper.denies(:edit) }\n\nit \"does not allow\"\n  expect(article).to receive(:allows).and_returns(no)\nend\n```\n\n## Model specs\n\n### EDIT\n\n`expect( article.allows( peon ).to_edit? ).to be false`\n\n`expect( article.allows( admin ).to_edit? ).to be true`\n\n### UPDATE\n\n`expect( article.allows( peon ).to_update? ).to be false`\n\n`expect( article.allows( admin ).to_update? ).to be true`\n\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/brentgreeff/fat_model_auth.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrentgreeff%2Ffat_model_auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrentgreeff%2Ffat_model_auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrentgreeff%2Ffat_model_auth/lists"}