Fossil

Diff
Login

Differences From Artifact [5200ec22cc]:

To Artifact [76d8108d18]:


173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199


200
201
202
203
204
205
206
**
** On error g.json's error state is set one of the FSL_JSON_E_xxx
** values from FossilJsonCodes is returned.
**
** On success the db record for the given user is updated.
**
** Requires either Admin, Setup, or Password access. Non-admin/setup
** users can only change their own information.
**
** TODOs:
**
** - Admin non-Setup users cannot change the information for Setup
** users.
**
*/
int json_user_update_from_json( cson_object * pUser ){
#define CSTR(X) cson_string_cstr(cson_value_get_string( cson_object_get(pUser, X ) ))
  char const * zName = CSTR("name");
  char const * zNameNew = zName;
  char * zNameFree = NULL;
  char const * zInfo = CSTR("info");
  char const * zCap = CSTR("capabilities");
  char const * zPW = CSTR("password");
  cson_value const * forceLogout = cson_object_get(pUser, "forceLogout");
  int gotFields = 0;
#undef CSTR
  cson_int_t uid = cson_value_get_integer( cson_object_get(pUser, "uid") );


  Blob sql = empty_blob;
  Stmt q = empty_Stmt;

  if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
    return json_set_err( FSL_JSON_E_DENIED,
                         "Password change requires 'a', 's', "
                         "or 'p' permissions.");







|
<
<
<
|
|














>
>







173
174
175
176
177
178
179
180



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
**
** On error g.json's error state is set one of the FSL_JSON_E_xxx
** values from FossilJsonCodes is returned.
**
** On success the db record for the given user is updated.
**
** Requires either Admin, Setup, or Password access. Non-admin/setup
** users can only change their own information. Non-setup users may



** not modify the 's' permission. Admin users without setup
** permissions may not edit any other user who has the 's' permission.
**
*/
int json_user_update_from_json( cson_object * pUser ){
#define CSTR(X) cson_string_cstr(cson_value_get_string( cson_object_get(pUser, X ) ))
  char const * zName = CSTR("name");
  char const * zNameNew = zName;
  char * zNameFree = NULL;
  char const * zInfo = CSTR("info");
  char const * zCap = CSTR("capabilities");
  char const * zPW = CSTR("password");
  cson_value const * forceLogout = cson_object_get(pUser, "forceLogout");
  int gotFields = 0;
#undef CSTR
  cson_int_t uid = cson_value_get_integer( cson_object_get(pUser, "uid") );
  char const tgtHasSetup = zCap && (NULL!=strchr(zCap, 's'));
  char tgtHadSetup = 0;
  Blob sql = empty_blob;
  Stmt q = empty_Stmt;

  if(!g.perm.Admin && !g.perm.Setup && !g.perm.Password){
    return json_set_err( FSL_JSON_E_DENIED,
                         "Password change requires 'a', 's', "
                         "or 'p' permissions.");
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
    }
    zName = zNameFree;
  }else if(-1==uid){
    /* try to create a new user */
    if(!g.perm.Admin && !g.perm.Setup){
      return json_set_err(FSL_JSON_E_DENIED,
                          "Requires 'a' or 's' privileges.");
    } else if(!zName || !*zName){
      return json_set_err(FSL_JSON_E_MISSING_ARGS,
                          "No name specified for new user.");
    }else if( db_exists("SELECT 1 FROM user WHERE login=%Q", zName) ){
      return json_set_err(FSL_JSON_E_RESOURCE_ALREADY_EXISTS,
                          "User %s already exists.", zName);
    }else{
      Stmt ins = empty_Stmt;







|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    }
    zName = zNameFree;
  }else if(-1==uid){
    /* try to create a new user */
    if(!g.perm.Admin && !g.perm.Setup){
      return json_set_err(FSL_JSON_E_DENIED,
                          "Requires 'a' or 's' privileges.");
    }else if(!zName || !*zName){
      return json_set_err(FSL_JSON_E_MISSING_ARGS,
                          "No name specified for new user.");
    }else if( db_exists("SELECT 1 FROM user WHERE login=%Q", zName) ){
      return json_set_err(FSL_JSON_E_RESOURCE_ALREADY_EXISTS,
                          "User %s already exists.", zName);
    }else{
      Stmt ins = empty_Stmt;
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265



266














267
268
269
270
271
272
273
  }

  /* Maintenance note: all error-returns from here on out should go
     via 'goto error' in order to clean up.
  */
  
  if(uid != g.userUid){
    /*
      TODO: do not allow an admin user to modify a setup user
      unless the admin is also a setup user. setup.c uses
      that logic. There is a corner case for a NEW Setup user
      which the admin is just installing. Hmm.      
    */
    if(!g.perm.Admin && !g.perm.Setup){
      json_set_err(FSL_JSON_E_DENIED,
                   "Changing another user's data requires "
                   "'a' or 's' privileges.");
    }
  }



  














  blob_append(&sql, "UPDATE USER SET",-1 );
  blob_append(&sql, " mtime=cast(strftime('%s') AS INTEGER)", -1);

  if((uid>0) && zNameNew){
    /* Check for name change... */
    if( (!g.perm.Admin && !g.perm.Setup)
        && zNameNew && (zName != zNameNew)







<
<
<
<
<
<






>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







246
247
248
249
250
251
252






253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  }

  /* Maintenance note: all error-returns from here on out should go
     via 'goto error' in order to clean up.
  */
  
  if(uid != g.userUid){






    if(!g.perm.Admin && !g.perm.Setup){
      json_set_err(FSL_JSON_E_DENIED,
                   "Changing another user's data requires "
                   "'a' or 's' privileges.");
    }
  }
  /* check if the target uid currently has setup rights. */
  tgtHadSetup = db_int(0,"SELECT 1 FROM user where uid=%d"
                       " AND cap GLOB '*s*'", uid);

  if((tgtHasSetup || tgtHadSetup) && !g.perm.Setup){
    /*
      Do not allow a non-setup user to set or remove setup
      privileges. setup.c uses similar logic.
    */
    return json_set_err(FSL_JSON_E_DENIED,
                        "Modifying 's' users/privileges requires "
                        "'s' privileges.");
  }
  /*
    Potential todo: do not allow a setup user to remove 's' from
    himself, to avoid locking himself out?
  */

  blob_append(&sql, "UPDATE USER SET",-1 );
  blob_append(&sql, " mtime=cast(strftime('%s') AS INTEGER)", -1);

  if((uid>0) && zNameNew){
    /* Check for name change... */
    if( (!g.perm.Admin && !g.perm.Setup)
        && zNameNew && (zName != zNameNew)