@@ -272,9 +272,19 @@ export class UsernameOrPasswordWrongError extends Error { }
272272
273273export class BackupsAccessDeniedError extends Error { }
274274
275+ export class UserAlreadyExistsError extends Error { }
276+
277+ export class UnknownUserAddError extends Error { }
278+
275279// Error parsing server response
276280export class ResponseParseError extends Error { }
277281
282+ export class UnknownUpdateRightsError extends Error { }
283+
284+ export class UnknownRemoveUserError extends Error { }
285+
286+ export class UnknownChangePasswordError extends Error { }
287+
278288export class BackupsAccessError extends Error {
279289 constructor ( message : string ) {
280290 super ( message ) ;
@@ -533,6 +543,54 @@ export interface LdapSettings
533543 settings : LdapSettingsVals ; // Settings
534544}
535545
546+ export interface UserRight
547+ {
548+ domain : string ; // Domain of the user right
549+ right : string ; // Right of the user. E.g. "all" or a list of client ids separated by commas
550+ }
551+
552+ export interface UserListItem
553+ {
554+ id : string ; // Id of the user (integer)
555+ name : string ; // Name of the user
556+ rights : UserRight [ ] ; // List of rights the user has
557+ }
558+
559+ export interface UserList
560+ {
561+ sa : "listusers" ; // Request settings sub-action
562+ navitems : SettingsNavitems ; // Navigation items
563+ users : UserListItem [ ] ; // List of users
564+ }
565+
566+ export enum AddUserResult {
567+ OK = 0 , // User was added successfully
568+ USERNAME_EXISTS = 1 , // Username already exists
569+ ERROR = 2 , // An error occurred
570+ }
571+
572+ function randomString ( )
573+ {
574+ var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz" ;
575+ var string_length = 50 ;
576+ var randomstring = '' ;
577+
578+ var array = new Uint32Array ( string_length ) ;
579+ if ( window . crypto && window . crypto . getRandomValues ( array ) )
580+ {
581+ for ( var i = 0 ; i < string_length ; i ++ ) {
582+ randomstring += chars . charAt ( array [ i ] % chars . length ) ;
583+ }
584+ return randomstring ;
585+ }
586+
587+ for ( var i = 0 ; i < string_length ; i ++ ) {
588+ var rnum = Math . floor ( Math . random ( ) * chars . length ) ;
589+ randomstring += chars . substring ( rnum , rnum + 1 ) ;
590+ }
591+ return randomstring ;
592+ }
593+
536594class UrBackupServer {
537595 private serverUrl : string ;
538596 private session = "" ;
@@ -1031,6 +1089,77 @@ class UrBackupServer {
10311089 return ret ;
10321090 }
10331091
1092+ getUserList = async ( ) => {
1093+ const resp = await this . fetchData ( { sa : "listusers" } , "settings" ) ;
1094+ return resp as UserList ;
1095+ }
1096+
1097+ // Add a user with the given name, password and rights
1098+ // Throws UserAlreadyExistsError if the user already exists on the server
1099+ createUser = async ( name : string , password : string , rights : UserRight [ ] ) => {
1100+ const salt = randomString ( ) ;
1101+ const password_md5 = MD5 ( salt + password ) . toString ( ) ;
1102+ const params : Record < string , string > = { sa : "useradd" , name : name , pwmd5 : password_md5 , salt : salt } ;
1103+ let i = 0 ;
1104+ let idx = "" ;
1105+ for ( const right of rights ) {
1106+ params [ i + "_domain" ] = right . domain ;
1107+ params [ i + "_right" ] = right . right ;
1108+ i ++ ;
1109+ if ( idx . length > 0 )
1110+ idx += "," ;
1111+ idx += "" + i ;
1112+ }
1113+ params [ "idx" ] = idx ;
1114+ const resp = await this . fetchData ( params , "settings" ) ;
1115+ if ( typeof resp . add_ok != "undefined" && resp . add_ok ) {
1116+ return ;
1117+ } else if ( typeof resp . alread_exists != "undefined" && resp . alread_exists ) {
1118+ throw new UserAlreadyExistsError ( ) ;
1119+ } else {
1120+ throw new UnknownUserAddError ( ) ;
1121+ }
1122+ }
1123+
1124+ // Change the rights of a user with the given userId
1125+ // Throws UnknownUpdateRightsError if the rights could not be updated
1126+ changeUserRights = async ( userId : string , rights : string ) => {
1127+ const params : Record < string , string > = { sa : "updaterights" , rights : rights , userid : userId } ;
1128+ const resp = await this . fetchData ( params , "settings" ) ;
1129+ if ( typeof resp . update_right != "undefined" && resp . update_right ) {
1130+ return resp as UserList ;
1131+ }
1132+
1133+ throw new UnknownUpdateRightsError ( ) ;
1134+ }
1135+
1136+ // Remove a user with the given userId
1137+ // Throws UnknownRemoveUserError if the user could not be removed
1138+ removeUser = async ( userId : string ) => {
1139+ const params : Record < string , string > = { sa : "removeuser" , userid : userId } ;
1140+ const resp = await this . fetchData ( params , "settings" ) ;
1141+ if ( typeof resp . removeuser != "undefined" && resp . removeuser ) {
1142+ return resp as UserList ;
1143+ }
1144+
1145+ throw new UnknownRemoveUserError ( ) ;
1146+ }
1147+
1148+ // Change the password of a user with the given userId
1149+ // Throws UnknownChangePasswordError if the password could not be changed
1150+ changeUserPassword = async ( userId : string , password : string ) => {
1151+ // TODO: Add function to change own password
1152+ const salt = randomString ( ) ;
1153+ const password_md5 = MD5 ( salt + password ) . toString ( ) ;
1154+ const params : Record < string , string > = { sa : "changepw" , userid : userId , pwmd5 : password_md5 , salt : salt } ;
1155+ const resp = await this . fetchData ( params , "settings" ) ;
1156+ if ( typeof resp . change_ok != "undefined" && resp . change_ok ) {
1157+ return resp as UserList ;
1158+ }
1159+
1160+ throw new UnknownChangePasswordError ( ) ;
1161+ }
1162+
10341163 // Get list of all client and group settings
10351164 settingsList = ( ) => {
10361165 return [
0 commit comments