/*
** 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");
cgi_printf("\n"
"\n"
" User ID | \n"
" Permissions | \n"
" In Real Life | \n"
"
\n");
azResult = db_query(
"SELECT id, name, email, capabilities FROM user ORDER BY id");
for(i=0; azResult[i]; i+= 4){
cgi_printf("\n"
"\n");
if( g.okAdmin ){
cgi_printf("\n",azResult[i]);
}
cgi_printf("%h\n",azResult[i]);
if( g.okAdmin ){
cgi_printf("\n");
}
cgi_printf(" | \n"
"%s | \n",azResult[i+3]);
if( azResult[i+2] && azResult[i+2][0] ){
char *zE = azResult[i+2];
cgi_printf("%h\n"
" (%h) | \n",azResult[i+1],zE,zE);
} else {
cgi_printf("%h | \n",azResult[i+1]);
}
cgi_printf("
\n");
}
cgi_printf("
\n"
"
\n"
"Notes:\n"
"\n"
"The permission flags are as follows:
\n"
"\n"
"a | | \n"
" Admin: Create or delete users and ticket report formats |
\n"
"d | | \n"
" Delete: Erase anonymous wiki, tickets, and attachments |
\n"
"i | | \n"
" Check-in: Add new code to the %h repository |
\n"
"j | | Read-Wiki: View wiki pages |
\n"
"k | | Wiki: Create or modify wiki pages |
\n"
"n | | New: Create new tickets |
\n"
"o | | \n"
" Check-out: Read code out of the %h repository |
\n"
"p | | Password: Change password |
\n"
"q | | Query: Create or edit report formats |
\n"
"r | | Read: View tickets and change histories |
\n"
"s | | Setup: Change CVSTrac options |
\n"
"w | | Write: Edit tickets |
\n"
"
\n"
"
\n"
"\n"
"\n"
"If a user named \"anonymous\" exists, then anyone can access\n"
"the server without having to log in. The permissions on the\n"
"anonymous user determine the access rights for anyone who is not\n"
"logged in.\n"
"
\n"
"\n",g.scm.zName,g.scm.zName);
if( !strcmp(g.scm.zSCM,"cvs") ){
cgi_printf("\n"
"You must be using CVS version 1.11 or later in order to give users\n"
"read-only access to the repository.\n"
"With earlier versions of CVS, all users with check-out\n"
"privileges also automatically get check-in privileges.\n"
"
\n"
"\n"
"\n"
"Changing a users ID or password modifies the CVSROOT/passwd,\n"
"CVSROOT/readers, and CVSROOT/writers files in the CVS\n"
"repository, if those files have write permission turned on. Users\n"
"IDs in CVSROOT/passwd that are unknown to CVSTrac are preserved.\n");
if( g.okSetup ){
cgi_printf("Use the \"Import CVS Users\" button on the \n"
"user setup page\n"
"to import CVS users into CVSTrac.\n");
}
cgi_printf("
\n");
}
cgi_printf("\n");
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?");
cgi_printf("\n",zId,zId);
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");
}
cgi_printf("\n");
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; }
}