Index: src/db.c ================================================================== --- src/db.c +++ src/db.c @@ -1584,10 +1584,11 @@ { "auto-captcha", "autocaptcha", 0, "on" }, { "auto-shun", 0, 0, "on" }, { "autosync", 0, 0, "on" }, { "binary-glob", 0, 32, "" }, { "clearsign", 0, 0, "off" }, + { "default-perms", 0, 16, "u" }, { "diff-command", 0, 16, "" }, { "dont-push", 0, 0, "off" }, { "editor", 0, 16, "" }, { "gdiff-command", 0, 16, "gdiff" }, { "ignore-glob", 0, 40, "" }, @@ -1596,10 +1597,11 @@ { "manifest", 0, 0, "off" }, { "mtime-changes", 0, 0, "on" }, { "pgp-command", 0, 32, "gpg --clearsign -o " }, { "proxy", 0, 32, "off" }, { "repo-cksum", 0, 0, "on" }, + { "self-register", 0, 0, "off" }, { "ssh-command", 0, 32, "" }, { "web-browser", 0, 32, "" }, { 0,0,0,0 } }; @@ -1634,10 +1636,14 @@ ** purposes. Example: *.xml ** ** clearsign When enabled, fossil will attempt to sign all commits ** with gpg. When disabled (the default), commits will ** be unsigned. Default: off +** +** default-perms Permissions given automatically to new users. For more +** information on permissions see Users page in Server +** Administration of the HTTP UI. Default: u. ** ** diff-command External command to run when performing a diff. ** If undefined, the internal text diff will be used. ** ** dont-push Prevent this repository from pushing from client to @@ -1677,10 +1683,15 @@ ** ** repo-cksum Compute checksums over all files in each checkout ** as a double-check of correctness. Defaults to "on". ** Disable on large repositories for a performance ** improvement. +** +** self-register Allow users to register themselves through the HTTP UI. +** This is useful if you want to see other names than +** "Anonymous" in e.g. ticketing system. On the other hand +** users can not be deleted. Default: off. ** ** ssh-command Command used to talk to a remote machine with ** the "ssh://" protocol. ** ** web-browser A shell command used to launch your preferred Index: src/login.c ================================================================== --- src/login.c +++ src/login.c @@ -266,10 +266,14 @@ } @ your user-id and password at the left and press the @ "Login" button. Your user name will be stored in a browser cookie. @ You must configure your web browser to accept cookies in order for @ the login to take.
+ if( db_get_boolean("self-register", 0) ){ + @If you do not have an account, you can + @ create one. + } if( zAnonPw ){ unsigned int uSeed = captcha_seed(); char const *zDecoded = captcha_decode(uSeed); int bAutoCaptcha = db_get_boolean("auto-captcha", 1); char *zCaptcha = captcha_render(zDecoded); @@ -624,5 +628,138 @@ g.okCsrf = 1; return; } fossil_fatal("Cross-site request forgery attempt"); } + +/* +** WEBPAGE: register +** +** Generate the register page. +** +*/ +void register_page(void){ + const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap; + if( !db_get_boolean("self-register", 0) ){ + style_header("Registration not possible"); + @
This project does not allow user self-registration. Please contact the + @ project administrator to obtain an account.
+ style_footer(); + return; + } + + style_header("Register"); + zUsername = P("u"); + zPasswd = P("p"); + zConfirm = P("cp"); + zContact = P("c"); + zCap = P("cap"); + zCS = P("cs"); /* Captcha Secret */ + + /* Try to make any sense from user input. */ + if( P("new") ){ + if( zCS==0 ) fossil_redirect_home(); /* Forged request */ + zPw = captcha_decode((unsigned int)atoi(zCS)); + if( !(zUsername && zPasswd && zConfirm && zContact) ){ + @+ @ All fields are obligatory. + @
+ }else if( strlen(zPasswd) < 6){ + @+ @ Password too weak. + @
+ }else if( strcmp(zPasswd,zConfirm)!=0 ){ + @+ @ The two copies of your new passwords do not match. + @
+ }else if( strcasecmp(zPw, zCap)!=0 ){ + @+ @ Captcha text invalid. + @
+ }else{ + /* This almost is stupid copy-paste of code from user.c:user_cmd(). */ + Blob passwd, login, caps, contact; + + blob_init(&login, zUsername, -1); + blob_init(&contact, zContact, -1); + blob_init(&caps, db_get("default-perms", "u"), -1); + blob_init(&passwd, zPasswd, -1); + + if( db_exists("SELECT 1 FROM user WHERE login=%B", &login) ){ + /* Here lies the reason I don't use zErrMsg - it would not substitute + * this %s(zUsername), or at least I don't know how to force it to.*/ + @+ @ %s(zUsername) already exists. + @
+ }else{ + char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login)); + db_multi_exec( + "INSERT INTO user(login,pw,cap,info)" + "VALUES(%B,%Q,%B,%B)", + &login, zPw, &caps, &contact + ); + free(zPw); + + /* The user is registered, now just log him in. */ + int uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername); + char *zCookie; + const char *zCookieName = login_cookie_name(); + const char *zExpire = db_get("cookie-expire","8766"); + int expires = atoi(zExpire)*3600; + const char *zIpAddr = PD("REMOTE_ADDR","nil"); + + zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); + cgi_set_cookie(zCookieName, zCookie, 0, expires); + db_multi_exec( + "UPDATE user SET cookie=%Q, ipaddr=%Q, " + " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", + zCookie, zIpAddr, expires, uid + ); + redirect_to_g(); + + } + } + } + + /* Prepare the captcha. */ + unsigned int uSeed = captcha_seed(); + char const *zDecoded = captcha_decode(uSeed); + char *zCaptcha = captcha_render(zDecoded); + + /* Print out the registration form. */ + @