#!/usr/bin/perl # TmNetWiki version 0.4 (September 11, 2002) # Copyright (C) 2002 Adam Brate # # Based on the GPLed UseModWiki 0.92 # Copyright (C) 2000-2001 Clifford A. Adams # or # Based on the GPLed AtisWiki 0.3 (C) 1998 Markus Denker # # ...which was based on # the LGPLed CVWiki CVS-patches (C) 1997 Peter Merel # and The Original WikiWikiWeb (C) Ward Cunningham # (code reused with permission) # Email and ThinLine options by Jim Mahoney # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc. # 59 Temple Place, Suite 330 # Boston, MA 02111-1307 USA package Wiki::user; use strict; # user methods # needs subs Wiki::page: PageIsLocked # Wiki::file: ReadFile, WriteStringToFile # Wiki::lock: RequestLock, ReleaseLock # Wiki::translate: T # Wiki::utility: GetRemoteHost, GetParam # needs consts UserDir, $ENV{'REMOTE_ADDR'}, AdminPass, EditPass, FS1 # needs vars %UserData, $UserID use base 'Exporter'; use Wiki::consts; use Wiki::page; use Wiki::file; use Wiki::lock; use Wiki::translate; use Wiki::utility; #if ($^V and $^V gt v5.6.0) { # our @EXPORT; #else { use vars qw(@EXPORT); #} @EXPORT = qw( LoadUserData GetNewUserId GetUserDataFile SaveUserData CreateUserDir UserCanEdit UserIsBanned UserIsAdmin GetUsers ); sub LoadUserData { my ($data, $status,$userData); %UserData = (); $userData = &_loadUserData($UserID); if ($userData->{uid} == 112) { $UserID = 112; return; } %UserData = %{$userData}; } sub _loadUserData { my ($userID) = @_; my ($data,$status,$userData); $userData = {}; ($status, $data) = &ReadFile(&GetUserDataFile($userID)); if (!$status) { $userData->{uid} = 112; # error value return $userData; } %{$userData} = split(/$Consts->{FS1}/, $data, -1); # -1 keeps trailing null fields return $userData; } # only used by DoNewLogin sub GetNewUserId { my ($id); $id = 1001; while (-f &GetUserDataFile($id+1000)) { $id += 1000; } while (-f &GetUserDataFile($id+100)) { $id += 100; } while (-f &GetUserDataFile($id+10)) { $id += 10; } &RequestLock() or die(T('Could not get user-ID lock')); while (-f &GetUserDataFile($id)) { $id++; } &WriteStringToFile(&GetUserDataFile($id), "lock"); # reserve the ID &ReleaseLock(); return $id; } # was named sub UserDataFilename sub GetUserDataFile { my ($id) = @_; return "" if ($id < 1); return $Consts->{UserDir} . "/" . ($id % 10) . "/$id.db"; } # user DB methods # Later get user-level lock sub SaveUserData { my ($userFile, $data); &CreateUserDir(); $userFile = &GetUserDataFile($UserID); $data = join($Consts->{FS1}, %UserData); &WriteStringToFile($userFile, $data); } # used by SaveUserData and DoNewLogin sub CreateUserDir { my ($n, $subdir); if (!(-d "$Consts->{UserDir}/0")) { &CreateDir($Consts->{UserDir}); foreach $n (0..9) { $subdir = "$Consts->{UserDir}/$n"; &CreateDir($subdir); } } } sub GetUsers { my ($n,$subdir,@users,$user,$usersText); &CreateUserDir(); foreach $n (0..9) { $subdir = "$Consts->{UserDir}/$n"; opendir DIR,$subdir; push @users, map { _loadUserData($_) } map {s/\.db$//} grep {/\.db/ && -f "$subdir/$_"} readdir(DIR); } foreach $user (sort { $a->{username} cmp $b->{username} } @users) { $usersText .= &GetAuthorLink('',$user->{username},$user->{uid})."
\n"; } return $usersText } #### # User methods #### sub UserCanEdit { my ($id, $deepCheck) = @_; # Optimized for the "everyone can edit" case (don't check passwords) if (($id ne "") && (&Wiki::page::PageIsLocked($id))) { return 1 if (&UserIsAdmin()); # Requires more privileges # Later option for editor-level to edit these pages? return 0; } if (!$Consts->{EditAllowed}) { return 1 if (&UserIsEditor()); return 0; } if (-f "$DataDir/noedit") { return 1 if (&UserIsEditor()); return 0; } if ($deepCheck) { # Deeper but slower checks (not every page) return 1 if (&UserIsEditor()); return 0 if (&UserIsBanned()); } return 1; } sub UserIsBanned { my ($host, $ip, $data, $status); ($status, $data) = &ReadFile("$DataDir/banlist"); return 0 if (!$status); # No file exists, so no ban $ip = $ENV{'REMOTE_ADDR'}; $host = &GetRemoteHost(0); foreach (split(/\n/, $data)) { next if ((/^\s*$/) || (/^#/)); # Skip empty, spaces, or comments return 1 if ($ip =~ /$_/i); return 1 if ($host =~ /$_/i); } return 0; } sub UserIsAdmin { my (@pwlist, $userPassword); return 0 if ($Consts->{AdminPass} eq ""); # no admins possible $userPassword = &GetParam("adminpw", ""); return 0 if ($userPassword eq ""); foreach (split(/\s+/, $Consts->{AdminPass})) { next if ($_ eq ""); return 1 if ($userPassword eq $_); } return 0; } sub UserIsEditor { my (@pwlist, $userPassword); return 1 if (&UserIsAdmin()); # Admin includes editor return 0 if ($Consts->{EditPass} eq ""); # no editors possible $userPassword = &GetParam("adminpw", ""); # Used for both return 0 if ($userPassword eq ""); foreach (split(/\s+/, $Consts->{EditPass})) { next if ($_ eq ""); return 1 if ($userPassword eq $_); } return 0; }