Fossil

Check-in [8c91be8b]
Login

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

Overview
Comment:Allow login using either the username or the first email address found in the USER.INFO column. Note that it might be useful to create an index on user(find_emailaddr(info)) to make this efficient in the case where there are many rows in the user table.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:8c91be8bf085e85f7755d3029ef03c8053d24239b86aac772c64ceccbb57c8f5
User & Date: drh 2018-08-10 16:44:48
References
2018-08-11
16:59
Fix to checkin [8c91be8b], which was intended to allow the user to log in with the email found in the contact info field of the user table. That checkin is fine as far as it goes, but it only works if the caller doesn't subsequently try to use the passed user name for anything else, since it isn't actually a user name. This checkin causes the low-level login checking function to re-point the user name pointer at the actual login name discovered while scanning for matching email addresses. check-in: 33522ff4 user: wyoung tags: login-with-email
Context
2018-08-10
16:51
Fix the /forum webpage so that it works even if the forumpost table does not exist in the repository. check-in: d73c5fd2 user: drh tags: trunk
16:44
Allow login using either the username or the first email address found in the USER.INFO column. Note that it might be useful to create an index on user(find_emailaddr(info)) to make this efficient in the case where there are many rows in the user table. check-in: 8c91be8b user: drh tags: trunk
16:16
Add the find_emailaddr() SQL function. check-in: 8a20d41f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/login.c.

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226



















227
228
229
230
231
232
233
** On serious (DB-level) error it will probably exit.
**
** zPassword may be either the plain-text form or the encrypted
** form of the user's password.
*/
int login_search_uid(const char *zUsername, const char *zPasswd){
  char *zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0);
  int const uid =
      db_int(0,
             "SELECT uid FROM user"
             " WHERE login=%Q"
             "   AND length(cap)>0 AND length(pw)>0"
             "   AND login NOT IN ('anonymous','nobody','developer','reader')"
             "   AND (pw=%Q OR (length(pw)<>40 AND pw=%Q))"
             "   AND (info NOT LIKE '%%expires 20%%'"
             "      OR substr(info,instr(lower(info),'expires')+8,10)>datetime('now'))",
             zUsername, zSha1Pw, zPasswd
             );



















  free(zSha1Pw);
  return uid;
}

/*
** Generates a login cookie value for a non-anonymous user.
**







<
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
** On serious (DB-level) error it will probably exit.
**
** zPassword may be either the plain-text form or the encrypted
** form of the user's password.
*/
int login_search_uid(const char *zUsername, const char *zPasswd){
  char *zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0);

  int uid = db_int(0,
    "SELECT uid FROM user"
    " WHERE login=%Q"
    "   AND length(cap)>0 AND length(pw)>0"
    "   AND login NOT IN ('anonymous','nobody','developer','reader')"
    "   AND (pw=%Q OR (length(pw)<>40 AND pw=%Q))"
    "   AND (info NOT LIKE '%%expires 20%%'"
    "      OR substr(info,instr(lower(info),'expires')+8,10)>datetime('now'))",
    zUsername, zSha1Pw, zPasswd
  );

  /* If we did not find a login on the first attempt, and the username
  ** looks like an email address, the perhaps the user entired their
  ** email address instead of their login.  Try again to match the user
  ** against email addresses contained in the "info" field.
  */
  if( uid==0 && strchr(zUsername,'@')!=0 ){
    Stmt q;
    db_prepare(&q,
      "SELECT login FROM user"
      " WHERE find_emailaddr(info)=%Q"
      "   AND instr(login,'@')==0",
      zUsername
    );
    while( uid==0 && db_step(&q)==SQLITE_ROW ){
       uid = login_search_uid(db_column_text(&q,0),zPasswd);
    }
    db_finalize(&q);
  }    
  free(zSha1Pw);
  return uid;
}

/*
** Generates a login cookie value for a non-anonymous user.
**