wiki.pl: Port some fixes from upstream
[Orgmuse.git] / modules / logout.pl
blob0e01818685e02adeb630293de2a618e9eb0f788a
1 #!/usr/bin/env perl
2 # ====================[ logout.pl ]====================
4 =head1 NAME
6 logout - An Oddmuse module for logging out the current Oddmuse user.
8 =head1 SYNOPSIS
10 logout logs out the current Oddmuse user from the current Oddmuse Wiki by
11 clearing that user's client-side, Oddmuse-specific HTML cookie. As this cookie
12 persists that user's username and and (optional) password for this Oddmuse Wiki,
13 clearing this cookie effectively logs that user off this Oddmuse Wiki.
15 Viola!
17 =head1 INSTALLATION
19 logout is easily installable: move this file into the B<wiki/modules/>
20 directory of your Oddmuse Wiki.
22 =cut
23 package OddMuse;
25 $ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/logout.pl">logout.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Logout_Extension">Logout Extension</a></p>';
27 # ....................{ CONFIGURATION }....................
29 =head1 CONFIGURATION
31 logout is easily configurable: set these variables in the B<wiki/config.pl>
32 file for your Oddmuse Wiki.
34 =cut
35 use vars qw($CommentsSuffix
36 $LogoutIsDebugging
39 =head2 $CommentsSuffix
41 A string that, unless blank, supplants that default
42 "${CommentsPrefix}${PageName}" link (e.g., "Comment on Logout_Extension")
43 in the edit bar with a new, page-agnostic
44 "${CommentsPrefix}${CommentsSuffix}" link (e.g., "Comment on this page"). Since
45 this string is blank, by default, it performs no such replacement. Enable it by
46 setting the string to some non-blank value in your B<wiki/config.pl> file; e.g.,
48 $CommentsSuffix = 'this page';
50 If you do set this variable, please also ensure that you have set the
51 C<$CommentsPrefix> variable. (If that variable is not set, but this variable is,
52 this variable is rudely ignored. Such is life in the insensate code trenches!)
54 This variable's intent is to lend some minute uniformity to the edit bar. All
55 the edit bar's other links ("Edit this page," "View other revisions",
56 "Administration," and so on) are page-agnostic; these links do not reference
57 the current page's name. Why, then, should the comment link be any different?
58 While an admittedly minor point, it is a point... This variable addresses it.
60 Lastly. Although this variable has, clearly, little relation to the cookie-
61 clearing implementation of the rest of this module, this module's author
62 conspired no better place for it - and therefore placed it here. (Do with it
63 what thou wilt, museful wrangler!)
65 =cut
66 #$CommentsSuffix = 'this page';
67 $CommentsSuffix = '';
69 =head2 $LogoutIsDebugging
71 A boolean that, if true, prints all key-value pairs (composing the currently
72 requested URL query and current user's cookie) with each Oddmuse Wiki page; and,
73 if false, does nothing. This boolean defaults to false.
75 Key-value pairs are printed by appending their contents onto Oddmuse's
76 C<$Message> variable, which Oddmuse then tacks onto the header for each page.
78 =cut
79 $LogoutIsDebugging = '';
81 # ....................{ ACTIONS }....................
82 $Action{logout} = \&DoLogout;
84 =head1 ACTIONS
86 =head2 DoLogout
88 Logs the current user "out."
90 This erases every entry in that user's client-side, site-specific cookie, which
91 has several unnerving effects:
93 =over
95 =item The user's currently cached username is discarded. As the username, in
96 the Oddmuse security model, is an aesthetic artifice having no relation
97 to whether that user is an editor, administrator, or merely 'visitor',
98 this doesn't do very much.
100 =item The user's currently cached password is discarded. If the user was logged
101 in as editor or administrator, that user is now logged off and, hereafter,
102 merely considered a 'visitor'.
104 =item All other key-value pairs are discarded. (This might serve as a decent
105 mechanism for testing cookie-specific functionality in your own module,
106 elsewhere.)
108 =back
110 =cut
111 sub DoLogout {
112 foreach my $cookieKey (keys %CookieParameters) { SetParam($cookieKey, ''); }
114 print
115 GetHeader('', Ts('Logged out of %s', $SiteName), '').
116 $q->div({-class=> 'content'}, T('You are now logged out.'));
117 PrintFooter();
120 # ....................{ FUNCTIONS }....................
121 *GetFooterLinksLogoutOld = *GetFooterLinks;
122 *GetFooterLinks = *GetFooterLinksLogout;
124 =head1 FUNCTIONS
126 =head2 GetFooterLinksLogout
128 Appends a "Logout" link onto the edit bar in the footer of each page.
130 =cut
131 sub GetFooterLinksLogout {
132 my ($page_name, $page_rev) = @_;
133 my $footer_links = GetFooterLinksLogoutOld(@_);
135 if ($CommentsPrefix and $CommentsSuffix) {
136 $footer_links =~ s
137 /(\Q<a class="comment\E.+?>).+?(<\/a>)
138 /$1.NormalToFree($CommentsPrefix.$CommentsSuffix).$2
139 /ex;
142 # Display the link to the "Logout" action iff the current user's already logged
143 # in with some username or password.
144 if (GetParam('username', '') ne '' or
145 GetParam('pwd', '') ne '') {
146 $footer_links =~ s
147 /(.+)(<\/.+?>)$
148 /$1.' '.ScriptLink('action=logout;id='.UrlEncode($id), T('Logout'), 'logout').$2
149 /ex;
152 return $footer_links;
155 =head2 CookieUsernameFix
157 Corrects the C<CookieUsernameFix> function, which, in its original definition,
158 caused a festering heap of trouble.
160 We suspect a flaw in the innate coding of that function. But, whatever the
161 fickle case, it's supplanted here with a (somewhat) stabler version.
163 =cut
164 sub CookieUsernameFix {
165 if ($LogoutIsDebugging) {
166 $Message .= "<table>";
168 $Message .= "<tr><td>QUERY::</td></tr>";
169 my %query_parameters = $q->Vars;
170 foreach my $query_parameter_name (keys %query_parameters) {
171 $Message .= "<tr>"
172 ."<td>${query_parameter_name}:</td>"
173 ."<td>$query_parameters{$query_parameter_name}</td></tr>";
176 $Message .= "<tr><td>COOKIE::</td></tr>";
177 my ($changed, $visible, %cookie_parameters) = CookieData();
178 foreach my $cookie_parameter (keys %cookie_parameters) {
179 $Message.="<tr>"
180 ."<td>${cookie_parameter}:</td>"
181 ."<td>$cookie_parameters{$cookie_parameter}</td></tr>";
184 $Message .= "</table>";
187 # Only valid usernames get stored in the new cookie.
188 my $name = GetParam('username', '');
189 if (!$name) { }
190 elsif (!$FreeLinks && !($name =~ /^$LinkPattern$/o)) {
191 CookieUsernameFixDelete(Ts('Invalid UserName %s: not saved.', $name));
193 elsif ($FreeLinks && (!($name =~ /^$FreeLinkPattern$/o))) {
194 CookieUsernameFixDelete(Ts('Invalid UserName %s: not saved.', $name));
196 elsif (length($name) > 50) { # Too long
197 CookieUsernameFixDelete(T('UserName must be 50 characters or less: not saved'));
201 sub CookieUsernameDelete {
202 $Message .= $q->p(shift);
203 $q->delete('username');
206 =head1 INTERFACE
208 logout considers an Oddmuse user to be logged in if and only if that user has
209 entered either some username or one of two site-wide passwords. (See
210 L<SECURITY>, below.)
212 If the current Oddmuse Wiki user is logged in, this module appends a "Logout"
213 link to the edit bar; if not, this module does not. (That, perchance, ill-named
214 edit bar is the second line of navigational, administerial links in the footer
215 for each page.)
217 If the current Oddmuse Wiki user is logged in and does click on that "Logout"
218 link in the edit bar, this module logs out that user by clearing the user's
219 client-side, site-specific cookie of all key-value pair content.
221 Oddmuse should, arguably, bundle this easy functionality into the main
222 Oddmuse script. It doesn't; so, we do it here.
224 =head1 SECURITY
226 logout inherits its security model from Oddmuse, to which it makes no serious
227 change. Now, Oddmuse has no pre-defined mechanism for managing users; rather,
228 when editing any editable page or commenting on any commentable page, anyone
229 may enter any username in the "Username:" edit field. That username need not
230 be registered, approved, or otherwise managed (as in other content management
231 systems). That username, as such, has no user-defined password, passphrase, or
232 other identifying token. Any user may masquerade as any other user, with happy
233 impunity!
235 logout retains this (admittedly loose) concept of a "user."
237 =head1 SEE ALSO
239 logout is "little brother" to the login module - from which it was inspired and
240 for which it's partly named, in antiparallel.
242 logout only implements a slim subset of functionality implemented by the logout
243 module. For a full-bodied, fully configurable alternative to Oddmuse security,
244 please use that module instead.
246 =head1 COPYRIGHT AND LICENSE
248 The information below applies to everything in this distribution,
249 except where noted.
251 Copyleft 2008 by B.w.Curry <http://www.raiazome.com>.
253 This file is free software; you can redistribute it and/or
254 modify it under the terms of the GNU General Public License
255 as published by the Free Software Foundation; either version 2
256 of the License, or (at your option) any later version.
258 This file is distributed in the hope that it will be useful,
259 but WITHOUT ANY WARRANTY; without even the implied warranty of
260 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
261 GNU General Public License for more details.
263 You should have received a copy of the GNU General Public License
264 along with this file; if not, write to the Free Software
265 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
267 =cut