/* ** Copyright (c) 2007 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/ ** ******************************************************************************* ** ** Implementation of the Setup page */ #include #include "config.h" #include "setup.h" /* ** Output a single entry for a menu generated using an HTML table. ** If zLink is not NULL or an empty string, then it is the page that ** the menu entry will hyperlink to. If zLink is NULL or "", then ** the menu entry has no hyperlink - it is disabled. */ void setup_menu_entry( const char *zTitle, const char *zLink, const char *zDesc ){ @
if( zLink && zLink[0] ){ @ %h(zTitle) }else{ @ %h(zTitle) } @
@
%h(zDesc)
} /* ** WEBPAGE: /setup */ void setup_page(void){ login_check_credentials(); if( !g.okSetup ){ login_needed(); } style_header("Setup"); @
setup_menu_entry("Users", "setup_ulist", "Grant privileges to individual users."); setup_menu_entry("Access", "setup_access", "Control access settings."); setup_menu_entry("Configuration", "setup_config", "Configure the WWW components of the repository"); setup_menu_entry("Tickets", "tktsetup", "Configure the trouble-ticketing system for this repository"); setup_menu_entry("CSS", "editcss", "Edit the Cascading Style Sheet used by all pages of this repository"); @
style_footer(); } /* ** WEBPAGE: setup_ulist ** ** Show a list of users. Clicking on any user jumps to the edit ** screen for that user. */ void setup_ulist(void){ Stmt s; login_check_credentials(); if( !g.okSetup ){ login_needed(); return; } style_submenu_element("Add", "Add User", "setup_uedit"); style_header("User List"); @ @
@ Users: @
@ @ @ @ db_prepare(&s, "SELECT uid, login, cap, info FROM user ORDER BY login"); while( db_step(&s)==SQLITE_ROW ){ @ @ @ @ @ } @
User ID @ Capabilities @ Contact Info
if( g.okAdmin ){ @ } @ %h(db_column_text(&s,1)) if( g.okAdmin ){ @ } @ %s(db_column_text(&s,2))%s(db_column_text(&s,3))
@
@ Notes: @
    @
  1. The permission flags are as follows:

    @
      @
    1. Admin: Create and delete users
    2. @
    3. Append-Tkt: Append to tickets
    4. @
    5. Delete: Delete wiki and tickets
    6. @
    7. Email: View EMail addresses on tickets
    8. @
    9. New-Wiki: Create new wiki pages
    10. @
    11. Clone: Clone the repository
    12. @
    13. History: View detail repository history
    14. @
    15. Check-In: Commit new versions in the repository
    16. @
    17. Read-Wiki: View wiki pages
    18. @
    19. Write-Wiki: Edit wiki pages
    20. @
    21. Append-Wiki: Append to wiki pages
    22. @
    23. New-Tkt: Create new tickets
    24. @
    25. Check-Out: Check out versions
    26. @
    27. Password: Change your own password
    28. @
    29. Query: Create new queries against tickets
    30. @
    31. Read-Tkt: View tickets
    32. @
    33. Setup: Setup and configure this website
    34. @
    35. Write-Tkt: Edit tickets
    36. @
    @

  2. @ @
  3. @ Every user, logged in or not, has the privileges of nobody. @ Any human can login as anonymous since the password is @ clearly displayed on the login page for them to type. The purpose @ of requiring anonymous to log in is to prevent access by spiders. @

  4. @ @
@
style_footer(); } /* ** WEBPAGE: /setup_uedit */ void user_edit(void){ const char *zId, *zLogin, *zInfo, *zCap; char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah, *oag, *oae; int doWrite; int uid; 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 = PD("id", "0"); uid = atoi(zId); if( zId && !g.okSetup && uid>0 ){ char *zOldCaps; zOldCaps = db_text(0, "SELECT caps FROM user WHERE uid=%d",uid); higherUser = zOldCaps && strchr(zOldCaps,'s'); } if( P("can") ){ cgi_redirect("setup_ulist"); 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 = cgi_all("login","info","pw") && !higherUser; if( doWrite ){ const char *zPw; const char *zLogin; char zCap[30]; int i = 0; int aa = P("aa")!=0; int ad = P("ad")!=0; int ae = P("ae")!=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; int ac = P("ac")!=0; int af = P("af")!=0; int am = P("am")!=0; int ah = P("ah")!=0; int ag = P("ag")!=0; if( aa ){ zCap[i++] = 'a'; } if( ac ){ zCap[i++] = 'c'; } if( ad ){ zCap[i++] = 'd'; } if( ae ){ zCap[i++] = 'e'; } if( af ){ zCap[i++] = 'f'; } if( ah ){ zCap[i++] = 'h'; } if( ag ){ zCap[i++] = 'g'; } if( ai ){ zCap[i++] = 'i'; } if( aj ){ zCap[i++] = 'j'; } if( ak ){ zCap[i++] = 'k'; } if( am ){ zCap[i++] = 'm'; } 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; zPw = P("pw"); if( zPw==0 || zPw[0]==0 ){ zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid); } zLogin = P("login"); if( uid>0 && db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid) ){ style_header("User Creation Error"); @ Login "%h(zLogin)" is already used by a different @ user. @ @

@

@ @ @ if( uid ){ @ }else{ @ } @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ if( !higherUser ){ @ @ @ } @
User ID:%d(uid) (new user)
Login:
Contact Info:
Capabilities: if( g.okSetup ){ @ Setup
} @ Admin
@ Delete
@ Email
@ Password
@ Query
@ Check-In
@ Check-Out
@ History
@ Clone
@ Read Wiki
@ New Wiki
@ Append Wiki
@ Write Wiki
@ Read Tkt
@ New Tkt
@ Append Tkt
@ Write Tkt @
Password:
  @
@

Notes:

@
    if( higherUser ){ @
  1. @ User %h(zId) has Setup privileges and you only have Admin privileges @ so you are not permitted to make changes to %h(zId). @

  2. @ } @ @
  3. @ The Delete privilege give the user the ability to erase @ wiki, tickets, and atttachments that have been added by anonymous @ users. This capability is intended for deletion of spam. The @ delete capability is only in effect for 24 hours after the item @ is first posted. The Setup user can delete anything at any time. @

  4. @ @
  5. @ The Query privilege allows the user to create or edit @ report formats by specifying appropriate SQL. Users can run @ existing reports without the Query privilege. @

  6. @ @
  7. @ An Admin user can add other users, create new ticket report @ formats, and change system defaults. But only the Setup user @ is able to change the repository to @ which this program is linked. @

  8. @ @
  9. @ The History privilege allows a user to see a timeline @ with hyperlinks to version information, to download ZIP archives @ of individual versions. @

  10. @ @
  11. @ No login is required for user "nobody". The capabilities @ of this user are available to anyone without supplying a username or @ password. To disable nobody access, make sure there is no user @ with an ID of nobody or that the nobody user has no @ capabilities enabled. The password for nobody is ignore. To @ avoid problems with spiders overloading the server, it is suggested @ that the 'h' (History) capability be turned off for user nobody. @

  12. @ @
  13. @ Login is required for user "anonymous" but the password @ is displayed on the login screen beside the password entry box @ so anybody who can read should be able to login as anonymous. @ On the other hand, spiders and web-crawlers will typically not @ be able to login. Set the capabilities of the anonymous user @ to things that you want any human to be able to do, but no any @ spider. @

  14. @ style_footer(); } /* ** Generate a checkbox for an attribute. */ static void onoff_attribute( const char *zLabel, /* The text label on the checkbox */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQParm, /* The query parameter */ int dfltVal /* Default value if VAR table entry does not exist */ ){ const char *zVal = db_get(zVar, 0); const char *zQ = P(zQParm); int iVal; if( zVal ){ iVal = atoi(zVal); }else{ iVal = dfltVal; } if( zQ==0 && P("submit") ){ zQ = "off"; } if( zQ ){ int iQ = strcmp(zQ,"on")==0 || atoi(zQ); if( iQ!=iVal ){ db_set(zVar, iQ ? "1" : "0", 0); iVal = iQ; } } if( iVal ){ @ %s(zLabel) }else{ @ %s(zLabel) } } /* ** Generate an entry box for an attribute. */ static void entry_attribute( const char *zLabel, /* The text label on the entry box */ int width, /* Width of the entry box */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQParm, /* The query parameter */ char *zDflt /* Default value if VAR table entry does not exist */ ){ const char *zVal = db_get(zVar, zDflt); const char *zQ = P(zQParm); if( zQ && strcmp(zQ,zVal)!=0 ){ db_set(zVar, zQ, 0); zVal = zQ; } @ @ %s(zLabel) } /* ** Generate a text box for an attribute. */ static void textarea_attribute( const char *zLabel, /* The text label on the textarea */ int rows, /* Rows in the textarea */ int cols, /* Columns in the textarea */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQParm, /* The query parameter */ char *zDflt /* Default value if VAR table entry does not exist */ ){ const char *zVal = db_get(zVar, zDflt); const char *zQ = P(zQParm); if( zQ && strcmp(zQ,zVal)!=0 ){ db_set(zVar, zQ, 0); zVal = zQ; } @ @ %s(zLabel) } /* ** WEBPAGE: setup_access */ void setup_access(void){ login_check_credentials(); if( !g.okSetup ){ login_needed(); } style_header("Access Control Settings"); db_begin_transaction(); @
    @
    onoff_attribute("Require password for local access", "localauth", "localauth", 1); @

    When enabled, the password sign-in is required for @ web access coming from 127.0.0.1. When disabled, web access @ from 127.0.0.1 is allows without any login - the user id is selected @ from the ~/.fossil database. Password login is always required @ for incoming web connections on internet addresses other than @ 127.0.0.1.

    @
    entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766"); @

    The number of hours for which a login is valid. This must be a @ positive number. The default is 8760 hours which is approximately equal @ to a year.

    @
    onoff_attribute("Allow anonymous signup", "anon-signup", "asu", 0); @

    Allow users to create their own accounts

    @
    @

    @
    db_end_transaction(0); style_footer(); } /* ** WEBPAGE: setup_config */ void setup_config(void){ login_check_credentials(); if( !g.okSetup ){ login_needed(); } style_header("WWW Configuration"); db_begin_transaction(); @
    @
    entry_attribute("Project Name", 60, "project-name", "pn", ""); @

    Give your project a name so visitors know what this site is about. @ The project name will also be used as the RSS feed title.

    @
    textarea_attribute("Project Description", 5, 60, "project-description", "pd", ""); @

    Describe your project. This will be used in page headers for search @ engines as well as a short RSS description.

    @
    @

    @
    db_end_transaction(0); style_footer(); } /* ** WEBPAGE: editcss */ void setup_editcss(void){ login_check_credentials(); if( !g.okSetup ){ login_needed(); } style_header("Edit CSS"); @
    @ Edit the CSS:
    textarea_attribute("", 40, 80, "css", "css", zDefaultCSS); @
    @ @
    style_footer(); }