/*
** Copyright (c) 2002 D. Richard Hipp
**
** 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 library; if not, write to the
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** Routines for handling user account
*/
#define _XOPEN_SOURCE
#include
#include "config.h"
#include "user.h"
/*
** WEBPAGE: /userlist
*/
void user_list(void){
char **azResult;
int i;
login_check_credentials();
if( !g.okWrite && g.isAnon ){
login_needed();
return;
}
common_standard_menu("userlist", 0);
common_add_help_item("CvstracAdminUsers");
common_add_action_item("useredit", "Add User");
common_header("User List");
@
@
@ User ID |
@ Permissions |
@ In Real Life |
@
azResult = db_query(
"SELECT id, name, email, capabilities FROM user ORDER BY id");
for(i=0; azResult[i]; i+= 4){
@
@
if( g.okAdmin ){
@
}
@ %h(azResult[i])
if( g.okAdmin ){
@
}
@ |
@ %s(azResult[i+3]) |
if( azResult[i+2] && azResult[i+2][0] ){
char *zE = azResult[i+2];
@ %h(azResult[i+1])
@ (%h(zE)) |
} else {
@ %h(azResult[i+1]) |
}
@
}
@
@
@ Notes:
@
@ The permission flags are as follows:
@
@ a | |
@ Admin: Create or delete users and ticket report formats |
@ d | |
@ Delete: Erase anonymous wiki, tickets, and attachments |
@ i | |
@ Check-in: Add new code to the %h(g.scm.zName) repository |
@ j | | Read-Wiki: View wiki pages |
@ k | | Wiki: Create or modify wiki pages |
@ n | | New: Create new tickets |
@ o | |
@ Check-out: Read code out of the %h(g.scm.zName) repository |
@ p | | Password: Change password |
@ q | | Query: Create or edit report formats |
@ r | | Read: View tickets and change histories |
@ s | | Setup: Change CVSTrac options |
@ w | | Write: Edit tickets |
@
@
@
@
@ If a user named "anonymous" exists, then anyone can access
@ the server without having to log in. The permissions on the
@ anonymous user determine the access rights for anyone who is not
@ logged in.
@
@
if( !strcmp(g.scm.zSCM,"cvs") ){
@
@ You must be using CVS version 1.11 or later in order to give users
@ read-only access to the repository.
@ With earlier versions of CVS, all users with check-out
@ privileges also automatically get check-in privileges.
@
@
@
@ Changing a users ID or password modifies the CVSROOT/passwd,
@ CVSROOT/readers, and CVSROOT/writers files in the CVS
@ repository, if those files have write permission turned on. Users
@ IDs in CVSROOT/passwd that are unknown to CVSTrac are preserved.
if( g.okSetup ){
@ Use the "Import CVS Users" button on the
@ user setup page
@ to import CVS users into CVSTrac.
}
@
}
@
common_footer();
}
/*
** WEBPAGE: /useredit
*/
void user_edit(void){
char **azResult;
const char *zId, *zName, *zEMail, *zCap;
char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
char *oak, *oad, *oaq;
int doWrite;
int higherUser = 0; /* True if user being edited is SETUP and the */
/* user doing the editing is ADMIN. Disallow editing */
/* Must have ADMIN privleges to access this page
*/
login_check_credentials();
if( !g.okAdmin ){ login_needed(); return; }
/* Check to see if an ADMIN user is trying to edit a SETUP account.
** Don't allow that.
*/
zId = P("id");
if( zId && !g.okSetup ){
char *zOldCaps;
zOldCaps = db_short_query(
"SELECT capabilities FROM user WHERE id='%q'",zId);
higherUser = zOldCaps && strchr(zOldCaps,'s');
}
if( !higherUser ){
if( P("delete") ){
common_add_action_item("userlist", "Cancel");
common_header("Are You Sure?");
@
common_footer();
return;
}else if( P("can") ){
cgi_redirect("userlist");
return;
}
}
/* If we have all the necessary information, write the new or
** modified user record. After writing the user record, redirect
** to the page that displays a list of users.
*/
doWrite = zId && zId[0] && cgi_all("nm","em","pw") && !higherUser;
if( doWrite ){
const char *zOldPw;
char zCap[20];
int i = 0;
int aa = P("aa")!=0;
int ad = P("ad")!=0;
int ai = P("ai")!=0;
int aj = P("aj")!=0;
int ak = P("ak")!=0;
int an = P("an")!=0;
int ao = P("ao")!=0;
int ap = P("ap")!=0;
int aq = P("aq")!=0;
int ar = P("ar")!=0;
int as = g.okSetup && P("as")!=0;
int aw = P("aw")!=0;
if( as ) aa = 1;
if( aa ) ai = aw = ap = 1;
if( aw ) an = ar = 1;
if( ai ) ao = 1;
if( ak ) aj = 1;
if( aa ){ zCap[i++] = 'a'; }
if( ad ){ zCap[i++] = 'd'; }
if( ai ){ zCap[i++] = 'i'; }
if( aj ){ zCap[i++] = 'j'; }
if( ak ){ zCap[i++] = 'k'; }
if( an ){ zCap[i++] = 'n'; }
if( ao ){ zCap[i++] = 'o'; }
if( ap ){ zCap[i++] = 'p'; }
if( aq ){ zCap[i++] = 'q'; }
if( ar ){ zCap[i++] = 'r'; }
if( as ){ zCap[i++] = 's'; }
if( aw ){ zCap[i++] = 'w'; }
zCap[i] = 0;
zOldPw = db_short_query("SELECT passwd FROM user WHERE id='%q'", zId);
db_execute("DELETE FROM user WHERE id='%q'", zId);
if( !P("delete2") ){
const char *zPw = P("pw");
char zBuf[3];
if( zOldPw==0 ){
char zSeed[100];
const char *z;
bprintf(zSeed,sizeof(zSeed),"%d%.20s",getpid(),zId);
z = crypt(zSeed, "aa");
zBuf[0] = z[2];
zBuf[1] = z[3];
zBuf[2] = 0;
zOldPw = zBuf;
}
db_execute(
"INSERT INTO user(id,name,email,passwd,capabilities) "
"VALUES('%q','%q','%q','%q','%s')",
zId, P("nm"), P("em"), zPw[0] ? crypt(zPw, zOldPw) : zOldPw, zCap
);
}else{
/* User was default assigned user id. Remove the default. */
db_execute( "DELETE FROM config WHERE "
" name='assignto' AND value='%q'", zId);
}
/*
** The SCM subsystem may be able to replicate the user db somewhere...
*/
if( g.scm.pxUserWrite ) g.scm.pxUserWrite(P("delete2")!=0 ? zId : 0);
cgi_redirect("userlist");
return;
}
/* Load the existing information about the user, if any
*/
zName = "";
zEMail = "";
zCap = "";
oaa = oad = oai = oaj = oak = oan = oao = oap = oaq = oar = oas = oaw = "";
if( zId ){
azResult = db_query(
"SELECT name, email, capabilities FROM user WHERE id='%q'", zId
);
if( azResult && azResult[0] ){
zName = azResult[0];
zEMail = azResult[1];
zCap = azResult[2];
if( strchr(zCap, 'a') ) oaa = " checked";
if( strchr(zCap, 'd') ) oad = " checked";
if( strchr(zCap, 'i') ) oai = " checked";
if( strchr(zCap, 'j') ) oaj = " checked";
if( strchr(zCap, 'k') ) oak = " checked";
if( strchr(zCap, 'n') ) oan = " checked";
if( strchr(zCap, 'o') ) oao = " checked";
if( strchr(zCap, 'p') ) oap = " checked";
if( strchr(zCap, 'q') ) oaq = " checked";
if( strchr(zCap, 'r') ) oar = " checked";
if( strchr(zCap, 's') ) oas = " checked";
if( strchr(zCap, 'w') ) oaw = " checked";
}else{
zId = 0;
}
}
/* Begin generating the page
*/
common_standard_menu(0,0);
common_add_help_item("CvstracAdminUsers");
common_add_action_item("userlist", "Cancel");
common_add_action_item(mprintf("useredit?delete=1&id=%t",zId), "Delete");
if( zId ){
common_header("Edit User %s", zId);
}else{
common_header("Add New User");
}
@
common_footer();
}
/*
** Remove the newline from the end of a string.
*/
void remove_newline(char *z){
while( *z && *z!='\n' && *z!='\r' ){ z++; }
if( *z ){ *z = 0; }
}