Fossil

Check-in [d70f5278]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance the functionality of the Login Group feature to allow administrators to enable Login Group self-registration.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | login-group-enhancements
Files: files | file ages | folders
SHA1:d70f52788462a57c84ad8e47f85030f24700efcd
User & Date: andybradford 2016-10-14 06:15:57
Context
2016-10-14
06:15
Enhance the functionality of the Login Group feature to allow administrators to enable Login Group self-registration. Leaf check-in: d70f5278 user: andybradford tags: login-group-enhancements
2016-10-13
14:52
Change webui.wiki to remove the exception about the download page, which is no longer the case. check-in: 47beb495 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/db.c.

2615
2616
2617
2618
2619
2620
2621

2622
2623
2624
2625
2626
2627
2628
....
2854
2855
2856
2857
2858
2859
2860



2861
2862
2863
2864
2865
2866
2867
  { "mv-rm-files",      0,              0, 0, 0, "off"                 },
#endif
  { "pgp-command",      0,             40, 0, 0, "gpg --clearsign -o " },
  { "proxy",            0,             32, 0, 0, "off"                 },
  { "relative-paths",   0,              0, 0, 0, "on"                  },
  { "repo-cksum",       0,              0, 0, 0, "on"                  },
  { "self-register",    0,              0, 0, 0, "off"                 },

  { "ssh-command",      0,             40, 0, 0, ""                    },
  { "ssl-ca-location",  0,             40, 0, 0, ""                    },
  { "ssl-identity",     0,             40, 0, 0, ""                    },
#ifdef FOSSIL_ENABLE_TCL
  { "tcl",              0,              0, 0, 0, "off"                 },
  { "tcl-setup",        0,             40, 1, 1, ""                    },
#endif
................................................................................
**                     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.
**
**    ssl-ca-location  The full pathname to a file containing PEM encoded
**                     CA root certificates, or a directory of certificates
**                     with filenames formed from the certificate hashes as







>







 







>
>
>







2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
....
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
  { "mv-rm-files",      0,              0, 0, 0, "off"                 },
#endif
  { "pgp-command",      0,             40, 0, 0, "gpg --clearsign -o " },
  { "proxy",            0,             32, 0, 0, "off"                 },
  { "relative-paths",   0,              0, 0, 0, "on"                  },
  { "repo-cksum",       0,              0, 0, 0, "on"                  },
  { "self-register",    0,              0, 0, 0, "off"                 },
  { "register-group",   0,              0, 0, 0, "off"                 },
  { "ssh-command",      0,             40, 0, 0, ""                    },
  { "ssl-ca-location",  0,             40, 0, 0, ""                    },
  { "ssl-identity",     0,             40, 0, 0, ""                    },
#ifdef FOSSIL_ENABLE_TCL
  { "tcl",              0,              0, 0, 0, "off"                 },
  { "tcl-setup",        0,             40, 1, 1, ""                    },
#endif
................................................................................
**                     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.
**
**    register-group   Apply the self-registration also to the login group if
**                     the repository is in a login group.
**
**    ssh-command      Command used to talk to a remote machine with
**                     the "ssh://" protocol.
**
**    ssl-ca-location  The full pathname to a file containing PEM encoded
**                     CA root certificates, or a directory of certificates
**                     with filenames formed from the certificate hashes as

Changes to src/login.c.

1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402









1403
1404








1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
....
1694
1695
1696
1697
1698
1699
1700









































        /* 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.*/
        @ <p><span class="loginError">
        @ %s(zUsername) already exists.
        @ </span></p>
      }else{
        char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);

        int uid;
        db_multi_exec(
            "INSERT INTO user(login,pw,cap,info,mtime)"
            "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
            &login, zPw, &caps, &contact
            );









        free(zPw);









        /* The user is registered, now just log him in. */
        uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
        login_set_user_cookie( zUsername, uid, NULL );
        redirect_to_g();

      }
    }
  }

  /* Prepare the captcha. */
  uSeed = captcha_seed();
  zDecoded = captcha_decode(uSeed);
................................................................................
  fossil_free(zSql);
  db_multi_exec(
    "DELETE FROM config "
    " WHERE name GLOB 'peer-*'"
    "    OR name GLOB 'login-group-*';"
  );
}
















































>






>
>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>




<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426

1427
1428
1429
1430
1431
1432
1433
....
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
        /* 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.*/
        @ <p><span class="loginError">
        @ %s(zUsername) already exists.
        @ </span></p>
      }else{
        char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login), 0);
        char *zErr = 0;
        int uid;
        db_multi_exec(
            "INSERT INTO user(login,pw,cap,info,mtime)"
            "VALUES(%B,%Q,%B,%B,strftime('%%s','now'))",
            &login, zPw, &caps, &contact
            );
        admin_log( "Registered user [%q] with capabilities [%q].",
                   blob_str(&login), blob_str(&caps) );
        if( login_group_name() && db_get_boolean("register-group", 0) ){
          login_group_apply(0, blob_str(&login), blob_str(&passwd), 
                            blob_str(&contact), blob_str(&caps), &zErr);
          admin_log( "Registered user [%q] in all login groups "
                     "with capabilities [%q].",
                     blob_str(&login), blob_str(&caps) );
        }
        free(zPw);

        if( zErr ){
          style_header("User Register Error");
          admin_log( "Error registering user '%q': %s'.", login, zErr );
          @ <p><span class="loginError">%s(zErr)</span></p>
          style_footer();
          fossil_free(zErr);
          return;
        }
        /* The user is registered, now just log him in. */
        uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
        login_set_user_cookie( zUsername, uid, NULL );
        redirect_to_g();

      }
    }
  }

  /* Prepare the captcha. */
  uSeed = captcha_seed();
  zDecoded = captcha_decode(uSeed);
................................................................................
  fossil_free(zSql);
  db_multi_exec(
    "DELETE FROM config "
    " WHERE name GLOB 'peer-*'"
    "    OR name GLOB 'login-group-*';"
  );
}

/*
** Apply user changes to the login group
**
** This routine will apply login information to repositories that are part
** of a login group.  If there is an error, memory will be allocated and an
** error string pointed to by pzErr which can be freed with fossil_free().
**
*/
void login_group_apply(
  const char *zOldLogin,     /* Old login name when changing login */
  const char *zLogin,        /* Login name to create or change */
  const char *zPw,           /* Password as shared secret */
  const char *zInfo,         /* Contact information for login */
  const char *zCap,          /* Capabilities to assign to login */
  char **pzErr               /* Variable in which error will be returned */
) {
  Blob sql;
  blob_zero(&sql);
  if( zOldLogin==0 ){
    blob_appendf(&sql,
      "INSERT INTO user(login)"
      "  SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
      zLogin, zLogin
    );
    zOldLogin = zLogin;
  }
  blob_appendf(&sql,
    "UPDATE user SET login=%Q,"
    "  pw=coalesce(shared_secret(%Q,%Q,"
            "(SELECT value FROM config WHERE name='project-code')),pw),"
    "  info=%Q,"
    "  cap=%Q,"
    "  mtime=now()"
    " WHERE login=%Q;",
    zLogin, zPw, zLogin, zInfo, zCap,
    zOldLogin
  );
  login_group_sql(blob_str(&sql), "<li> ", " </li>\n", pzErr);
  blob_reset(&sql);
}

Changes to src/setup.c.

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
       "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
       "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
      uid, zLogin, P("info"), zPw, zCap
    );
    admin_log( "Updated user [%q] with capabilities [%q].",
               zLogin, zCap );
    if( atoi(PD("all","0"))>0 ){
      Blob sql;
      char *zErr = 0;
      blob_zero(&sql);
      if( zOldLogin==0 ){
        blob_appendf(&sql,
          "INSERT INTO user(login)"
          "  SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);",
          zLogin, zLogin
        );
        zOldLogin = zLogin;
      }
      blob_appendf(&sql,
        "UPDATE user SET login=%Q,"
        "  pw=coalesce(shared_secret(%Q,%Q,"
                "(SELECT value FROM config WHERE name='project-code')),pw),"
        "  info=%Q,"
        "  cap=%Q,"
        "  mtime=now()"
        " WHERE login=%Q;",
        zLogin, P("pw"), zLogin, P("info"), zCap,
        zOldLogin
      );
      login_group_sql(blob_str(&sql), "<li> ", " </li>\n", &zErr);
      blob_reset(&sql);

      admin_log( "Updated user [%q] in all login groups "
                 "with capabilities [%q].",
                 zLogin, zCap );
      if( zErr ){
        style_header("User Change Error");
        admin_log( "Error updating user '%q': %s'.", zLogin, zErr );
        @ <span class="loginError">%s(zErr)</span>







<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>







455
456
457
458
459
460
461

462






















463
464
465
466
467
468
469
470
       "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
       "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
      uid, zLogin, P("info"), zPw, zCap
    );
    admin_log( "Updated user [%q] with capabilities [%q].",
               zLogin, zCap );
    if( atoi(PD("all","0"))>0 ){

      char *zErr = 0;






















      login_group_apply(zOldLogin, zLogin, P("pw"), P("info"), zCap, &zErr);
      admin_log( "Updated user [%q] in all login groups "
                 "with capabilities [%q].",
                 zLogin, zCap );
      if( zErr ){
        style_header("User Change Error");
        admin_log( "Error updating user '%q': %s'.", zLogin, zErr );
        @ <span class="loginError">%s(zErr)</span>