{"id":13508148,"url":"https://github.com/sugar-framework/plugs","last_synced_at":"2025-10-21T18:54:39.695Z","repository":{"id":13976714,"uuid":"16677461","full_name":"sugar-framework/plugs","owner":"sugar-framework","description":"A collection of Plug middleware for web applications","archived":false,"fork":false,"pushed_at":"2024-08-29T19:03:59.000Z","size":36,"stargazers_count":19,"open_issues_count":1,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-03T06:45:50.891Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/plugs","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"donnemartin/data-science-ipython-notebooks","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sugar-framework.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-09T22:28:42.000Z","updated_at":"2024-12-11T22:05:42.000Z","dependencies_parsed_at":"2022-07-31T17:09:04.106Z","dependency_job_id":null,"html_url":"https://github.com/sugar-framework/plugs","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sugar-framework%2Fplugs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sugar-framework%2Fplugs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sugar-framework%2Fplugs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sugar-framework%2Fplugs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sugar-framework","download_url":"https://codeload.github.com/sugar-framework/plugs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246301963,"owners_count":20755512,"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-08-01T02:00:48.913Z","updated_at":"2025-10-21T18:54:34.666Z","avatar_url":"https://github.com/sugar-framework.png","language":"Elixir","funding_links":[],"categories":["Framework Components"],"sub_categories":[],"readme":"# Plugs\n\n## `Sugar.Plugs.HotCodeReload`\n\nUsed to add hot code reloading to a project, preventing the need to stop, recompile, and start your application to see your changes.\n\nUse:\n\n```elixir\ndefmodule MyRouter do\n  use Plug.Router\n\n  plug Sugar.Plugs.HotCodeReload\n\n  plug :match\n  plug :dispatch\n\n  # Rest of router definition\n  ...\nend\n```\n\n## `Sugar.Plugs.EnsureAuthenticated`\n\nUsed to ensure that a user is currently logged on before proceeding through a Plug pipeline.  This is designed first and foremost for [Sugar](http://sugar-framework.github.io), but it can hypothetically work with any plug-based app (emphasis on \"hypothetically\").\n\n### Setup\n\nIn your `router.ex`:\n\n```elixir\ndefmodule MyApp.Router do\n  use Sugar.Router\n\n  plug :put_secret_key_base\n  plug Plug.Session,\n    store: :cookie,\n    key: \"_my_app_session\",\n    encryption_salt: \"encryption salt\",\n    signing_salt: \"signing salt\",\n    key_length: 64\n\n  def put_secret_key_base(conn, _) do\n    base = \"some 64 character random string\"\n    put_in conn.secret_key_base, base\n  end\n\n  # ...\n\nend\n```\n\nYou'll also want a controller to present a login page and authenticate a user (and possibly act on `conn.params[\"return_to\"]`; see below).\n\n### Use\n\nAdd this to a controller you want authentication on:\n\n```elixir\ndefmodule MyApp.Controllers.Foo do\n  use Sugar.Controller\n\n  plug Sugar.Plugs.EnsureAuthenticated\n\n  # ...\n\nend\n```\n\nIf your controller has some actions that don't need authentication, then you can use `plug Sugar.Plugs.EnsureAuthenticated, except: [:foo, :bar]`.  Likewise, if your controller's actions mostly don't require authentication, you can use `plug Sugar.Plugs.EnsureAuthenticated, only: [:baz, :bat]`.  Only specify one or the other (`:only` *should* take precedence in the event that both are used).\n\n### Configuration\n\n`Sugar.Plugs.EnsureAuthenticated` defaults to expect the following:\n\n* You have an Ecto repo at `MyApp.Repos.Main`\n* You have a User model at `MyApp.Models.User`\n* Users should be directed to your app's `/login` route if they're not currently logged in\n\nThe first two can be overridden by calling the plug as `plug Sugar.Plugs.EnsureAuthenticated, repo: My.Custom.Repo, model: My.Custom.Model` (should be self-explanatory).  The third can't be changed quite yet (TODO: add that configuration option), at least not without implementing a custom handler (see below).\n\n#### `:return_to` (`:origin` or an explicit URL)\n\nOne can provide a `:return_to` option, which adds a query parameter (named `return_to` by default) to signal to a login page where the user should be redirected to after logging in.  The most automatic approach would be to set this to `:origin`, like so:\n\n```elixir\nplug Sugar.Plugs.EnsureAuthenticated, return_to: :origin\n```\n\nThe above reads the connection's original path and sets `conn.params[\"return_to\"]` automatically.\n\n#### Custom Handler\n\nBy default, `Sugar.Plugs.EnsureAuthenticated` uses a built-in handler to check for authentication.  This handler is pretty minimal in terms of what it does:\n\n* Checks to see if the controller action being run actually requires authentication (by checking `conn.private.action` for an action name); if not, then continues without doing anything else.\n* Checks to see if there's a \"user_id\" session key (if not, then redirects to \"/login\")\n* Fetches a `%MyApp.Models.User{}` (or the struct for whatever model you've configured) from `MyApp.Repos.Main` (or whatever repo you've configured); if it can't find a user, then redirects to \"/login\"\n* Assigns the found user to the connection's `:current_user` (for use by other plugs, namely [Canary](https://github.com/cpjk/canary)), then continues on the pipeline\n\nIf you need to implement custom functionality (for example, if you're not using Sugar-compatible controllers, or if you're not using Ecto models), you can call `plug Sugar.Plugs.EnsureAuthenticated, handler: {MyApp.Auth.Handler, :verify}` (where `MyApp.Auth.Handler` is a module and `:verify` is the name of a function in that module; you could also do `handler: MyApp.Auth.Handler`, in which case the `:verify` function will be called).\n\nIn order to work, the handler must accept both a `%Plug.Conn{}` (i.e. a `conn` variable, like in a typical plug) and a `Map` containing the options passed to `EnsureAuthenticated`.  From here, you can implement whatever checks you need to perform.\n\n### To Do\n\n* Allow more things to be customized without having to implement a custom handler\n* Move default values from hard-coded to `config.exs`-based configuration\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsugar-framework%2Fplugs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsugar-framework%2Fplugs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsugar-framework%2Fplugs/lists"}