The declaration, made beside a model or a page, of which of its routes require a signed in user.
A data record rather than a trait with methods, because it is the concept and not the mechanism: modules/auth ships one way of signing in, and any other, a single sign on or an API key, has to produce one of these and nothing else. http therefore has no guard in it at all, which is what keeps a login page out of an application that has no users.
Four fields, and each is one question a route table has to answer.
actions is which of the seven the declaration covers, so a model can guard writing and leave reading public. A page rather than a model is Guarded[Index.type], whose routes are handwritten and have no Action between them; for those the set is not read and the wrapper reaches the route directly. through is the wrapper. It is a Route => Route rather than a Handler => Handler because refusing a Route.Ws is not refusing a Route.Http: one answers a redirect and the other cannot, and only something holding the whole route can tell them apart.
Guarding Create while leaving New open, or Update while leaving Edit open, raises no warning, and that is a decision rather than an omission. The Orphan warning next door exists because a form page whose submit target is not mounted is a guaranteed 405 with no reading under which the author meant it. This is not that: the target is mounted and answers correctly, with a 303 to the login page, which is what a login redirect is for. A form anyone may fill in and only a signed in user may submit is a shape somebody will want on purpose, and warning about it would be eezo having an opinion about a page's design rather than reporting a route that cannot work.
carries is the guard's own routes, the login page and the logout button, travelling inside every declaration that guard produced. That is what makes them impossible to forget: an application that guards one route has mounted the page that route redirects to, without writing a line. It also means the same route instances appear in many declarations, so the route table concatenates them and takes distinct; two equal but separate instances would mount the login page twice and RouteTable's duplicate check would refuse to boot.
identify is the gentle half of through: it names the current user on a request and never refuses one. The two are separate because refusing and naming happen in different places. A guarded page is refused and named by the same wrapper, so through does both for it; an upgrade has no wrapper the table can reach around a public route, so the table composes the identify of every declaration mounted into it and runs that on the handshake. A declaration that knows nobody, Guarded.public and any built before there was anything to name, hands the request back exactly as it came.
Not final, and that is the one concession this type makes to Owned. Ownership is a refinement of being guarded rather than a second kind of declaration beside it, so an owned model declares one thing and the route table's lookup, its mounting and every call site that takes a Guarded[A] stay exactly as they were. The alternative, a separate type, would mean every one of those places learning a second one and an owned model writing two lines that have to agree.
Being open is also why it is a plain class with plain vals rather than a case class. A case class that something extends lies about all three of the things case generates: an Owned would equal a bare Guarded carrying the same four fields, two Owned differing only in what they cover or whose field records the owner would equal each other, and copy on an Owned would hand back a plain Guarded with the ownership silently gone. A declaration is read for its fields and never copied or compared, so nothing here wants those; what it wants is that a refinement of it stays one.
There is deliberately no default given. Actions has one, because saying nothing about which routes a model mounts means all seven, which is a safe silence. Saying nothing about who may reach them is not: a default of public would make an unguarded route the thing a user gets by forgetting, and a default of guarded would make every application need a guard. Silence is a compile error instead, in an application whose build declares eezo-auth, and means public anywhere else. A declaration that exists is used either way, which is the rule the sbt plugin's generator enforces.
Attributes
- Companion
- object
- Source
- Guarded.scala
- Graph
-
- Supertypes
- Known subtypes