From: http://anastigmatix.net/ Date: Sun, 19 Oct 2014 21:07:15 +0000 (-0400) Subject: initial description of signinview plugin X-Git-Tag: 3.20150107~118 X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/commitdiff_plain/9a4fab05e079a0da6fad26c78213da51f8bfb043?ds=sidebyside;hp=-c initial description of signinview plugin --- 9a4fab05e079a0da6fad26c78213da51f8bfb043 diff --git a/doc/plugins/contrib/signinview.mdwn b/doc/plugins/contrib/signinview.mdwn new file mode 100644 index 000000000..6fc9cd9ce --- /dev/null +++ b/doc/plugins/contrib/signinview.mdwn @@ -0,0 +1,144 @@ +[[!template id=plugin name=signinview core=0 author="[[jcflack]]"]] +[[!tag type/special-purpose]] + +This plugin is one implementation approach to a [[todo/zoned ikiwiki]]. It is named +like [[plugins/signinedit]], which requires users to sign in before editing pages. +Similarly, this plugin requires users to sign in before _viewing_ certain pages. +Unlike [[plugins/signinedit]], which _only_ checks that any user is signed in, +this plugin is also similar to [[plugins/lockedit]] in that it checks the user's +identity and a [[ikiwiki/PageSpec]] to determine _which_ pages may be viewed. +It works with any auth methods ikiwiki supports, not only those the `http` server +also understands. + +## How to configure + +This plugin adds a new function, `do=view`, to ikiwiki's CGI wrapper. It is intended +to be called by the `http` server as an `ErrorDocument` for the `403` (forbidden) error response. + +In order to be usable even in shared-hosting situations without full access to +the `http` server configuration files, this plugin requires nothing more than +`.htaccess` files, as long as the server is configured to honor `ErrorDocument` and +`Deny` or `Require` directives in them. + +To divide the wiki into a public zone and one or more private zone(s), simply place +`Require all denied` (Apache 2.4), `Deny from All` (Apache 2.2), or the equivalent +directive for the server and version in use, on the topmost directory of any private +zone, either in an `.htaccess` file, or in the server configuration file if possible. +Any location outside of these will continue to be served as normal public static +ikiwiki content. + +Then, if the `{$cgiurl}` is, for example, `/cgi-bin/ikiwiki.cgi`, add the directive + + ErrorDocument 403 /cgi-bin/ikiwiki.cgi?do=view + +at the private locations or any ancestor up to the documentroot itself, again either +in a `.htaccess` file or in the server configuration file. + +That's it for the server configuration. The server will now punt every request for +private content to the ikiwiki wrapper. Everything else about the authorization +decision--what auth method to use, whether there is just one private zone or different +zones for different users--is handled by ikiwiki using a [[ikiwiki/PageSpec]]. + +### viewable_pages config option + +This option in `ikiwiki.setup` is a [[ikiwiki/PageSpec]] defining which pages can be viewed. +Because one predicate that can be used in a [[ikiwiki/PageSpec]] is `user`, this is enough +to define interesting access rules. For example: + + viewable_pages: > + ((user(astolfo) or user(basilio)) and team1/*) + or + ((user(clotaldo) or user(estrella)) and team2/*) + +Note that this defines the conditions to _allow_ viewing, which is opposite the +sense of the [[plugins/lockedit]] plugin, where you define the conditions +to _deny_ editing. + +If there are more than a few users in a group, or the specification for accessible +pages is more complex, the [[plugins/contrib/pagespec_alias]] plugin +can be useful to factor things out. Note it currently must [[be patched|plugins/contrib/pagespec_alias/discussion]] +for this to work: + + pagespec_aliases: + team1: > + user(astolfo) + or user(basilio) + team2: > + user(clotaldo) + or user(estrella) + team1stuff: team1/* or common/* + team2stuff: team2/* or common/* + viewable_pages: > + (team1() and team1stuff()) + or (team2() and team2stuff()) + +### mime_types config option + +Normally, when serving the static pages of an ordinary public site, +the `http` server itself is responsible for identifying the `Content-Type` +of each file. However, for any page that is served by this plugin instead +of directly, the CGI specification makes it [plugin's job](http://tools.ietf.org/html/rfc3875#section-6.3.1), +not the server's, to identify the `Content-Type`. + +In the current version, this plugin does that in a dead-simple way. For any page that ikiwiki htmlized +(that is, for which the `pagetype` [[plugin API function|plugins/write]] returns a value), +the type `text/html` is assigned. For anything else, a simple collection of content types and `PageSpec`s +must be configured in the `ikiwiki.setup` file: + + mime_types: + image/png: '*.png' + application/pdf: '*.pdf' + text/css: '*.css' + +Anything without a matching rule gets served as `application/octet-stream`, which is +probably not what you want, but a clear sign of what rule needs to be added. + +## Other considerations + +### Leakage of non-content files + +Any CGI code that does what this plugin does, and can serve requested files under the +document root, needs to be careful not to allow viewing of certain sensitive files +that may also be found there, such as `.htaccess`, `.htpasswd`, etc. Instead of trying +to think of all the possible files that should not be served, this plugin takes an +absolutely strict approach: every requested file is looked up in the `%destsources` hash, +containing all the files ikiwiki has generated or placed in the web root. +Any file that _ikiwiki didn't put there_, this plugin _won't touch_. Otherwise, its page +name is now known, and must satisfy the `viewable_pages` `PageSpec`. + +This policy is also what allows this plugin to work back through `%pagesources` to +the original source name, needed for the content-type rules described above. + +### Cache control + +The purpose of a non-public zone can be defeated if there are caching proxies or +other non-private caches that might retain the content this plugin returns. + +Caching of the response is automatically forbidden by the HTTP specification +[if there was an `Authorization` header in the request](http://tools.ietf.org/html/rfc7234#section-3.2). +However, this plugin works with any auth method ikiwiki supports, not all of which require +that header, so this plugin always emits response headers to explicitly forbid caching. + +Note that nothing precludes an evil caching agent that ignores the rules. + +### Other ways to handle `Content-Type` + +While it is simple enough to supply a `mime_types` map in `ikiwiki.setup`, it also +duplicates logic that has already been done to death in other places. Another approach +would be to use `File::MimeInfo::Magic`, which is already present if the `filecheck` +plugin is in use. + +In a wiki _compiler_, it would be natural to do that content-type determination +at compile time and save it in page state, so this plugin would simply output +the stored type. On the other hand, saving the type for every (non-htmlized?) page +would enlarge the state `Storable` that has to be loaded, and so might not be +faster than typing the file on the fly. + +## Obtaining and installing + +The `signinview` plugin is [not in github yet](https://github.com/jcflack/ikiwiki/tree/plug-signinview) +(horroars! vaporware!). What _is_ in github at the moment is a preliminary patch I have proposed, +giving plugins some control over the environment variables that a generated wrapper will preserve. + +Depending on the ultimate fate of that patch, I will adjust/rebase and then push the `signinview` +branch itself.