pymensago/iscmds.py
def register(conn: ServerConnection, uid: utils.UserID, pwhash: str, devid: utils.UUID,
	devicekey: CryptoString) -> RetVal:
	'''Creates an account on the server.'''
	
	if not uid.is_valid():
		return RetVal(ErrBadValue, 'invalid user ID')
		
	# This construct is a little strange, but it is to work around the minute possibility that
	# there is a WID collision, i.e. the WID generated by the client already exists on the server.
	# In such an event, it should try again. However, in the ridiculously small chance that the 
	# client keeps generating collisions, it should wait 3 seconds after 10 collisions to reduce 
	# server load.
	out = RetVal()
	wid = utils.UUID()
	response = dict()
	tries = 1
	while wid.is_empty():
		if not tries % 10:
			time.sleep(3.0)
		
		# Technically, the active profile already has a WID, but it is not attached to a domain and
		# doesn't matter as a result. Rather than adding complexity, we just generate a new UUID
		# and always return the replacement value
		wid.generate()
		request = {
			'Action' : 'REGISTER',
			'Data' : {
				'Workspace-ID' : wid.as_string(),
				'Password-Hash' : pwhash,
				'Device-ID' : devid.as_string(),
				'Device-Key' : devicekey.as_string()
			}
		}
		if uid:
			request['Data']['User-ID'] = uid.as_string()

		status = conn.send_message(request)
		if status.error():
			return status

		response = conn.read_response(server_response)
		if response.error():
			return response
		
		if response['Code'] in [ 101, 201]:		# Pending, Success
			out.set_values({
				'devid' : devid,
				'wid' : wid,
				'domain' : utils.Domain(response['Data']['Domain']),
				'uid' : uid
			})
			break
		
		if response['Code'] == 408:	# WID or UID exists
			if 'Field' not in response['Data']:
				return RetVal(ErrServerError, 'server sent 408 without telling what existed')
			
			if response['Data']['Field'] not in ['User-ID', 'Workspace-ID']:
				return RetVal(ErrServerError, 'server sent bad 408 response').set_value( \
					'Field', response['Data']['Field'])

			if response['Data']['Field'] == 'User-ID':
				return RetVal(ErrExists, 'user id')
			
			tries = tries + 1
			wid.set('')
		else:
			# Something we didn't expect -- reg closed, payment req'd, etc.
			return wrap_server_error(response)
	
	return out
Creates an account on the server.
Creates an account on the server.
Creates an account on the server .
def register(conn: ServerConnection, uid: utils.UserID, pwhash: str, devid: utils.UUID,
	devicekey: CryptoString) -> RetVal:
	if not uid.is_valid():
		return RetVal(ErrBadValue, 'invalid user ID')
	out = RetVal()
	wid = utils.UUID()
	response = dict()
	tries = 1
	while wid.is_empty():
		if not tries % 10:
			time.sleep(3.0)
		wid.generate()
		request = {
			'Action' : 'REGISTER',
			'Data' : {
				'Workspace-ID' : wid.as_string(),
				'Password-Hash' : pwhash,
				'Device-ID' : devid.as_string(),
				'Device-Key' : devicekey.as_string()
			}
		}
		if uid:
			request['Data']['User-ID'] = uid.as_string()
		status = conn.send_message(request)
		if status.error():
			return status
		response = conn.read_response(server_response)
		if response.error():
			return response
		if response['Code'] in [ 101, 201]:		
			out.set_values({
				'devid' : devid,
				'wid' : wid,
				'domain' : utils.Domain(response['Data']['Domain']),
				'uid' : uid
			})
			break
		if response['Code'] == 408:	
			if 'Field' not in response['Data']:
				return RetVal(ErrServerError, 'server sent 408 without telling what existed')
			if response['Data']['Field'] not in ['User-ID', 'Workspace-ID']:
				return RetVal(ErrServerError, 'server sent bad 408 response').set_value( \
					'Field', response['Data']['Field'])
			if response['Data']['Field'] == 'User-ID':
				return RetVal(ErrExists, 'user id')
			tries = tries + 1
			wid.set('')
		else:
			return wrap_server_error(response)
	return out
def register ( conn : ServerConnection , uid : utils . UserID , pwhash : str , devid : utils . UUID , devicekey : CryptoString ) -> RetVal : if not uid . is_valid ( ) : return RetVal ( ErrBadValue , 'invalid user ID' ) out = RetVal ( ) wid = utils . UUID ( ) response = dict ( ) tries = 1 while wid . is_empty ( ) : if not tries % 10 : time . sleep ( 3.0 ) wid . generate ( ) request = { 'Action' : 'REGISTER' , 'Data' : { 'Workspace-ID' : wid . as_string ( ) , 'Password-Hash' : pwhash , 'Device-ID' : devid . as_string ( ) , 'Device-Key' : devicekey . as_string ( ) } } if uid : request [ 'Data' ] [ 'User-ID' ] = uid . as_string ( ) status = conn . send_message ( request ) if status . error ( ) : return status response = conn . read_response ( server_response ) if response . error ( ) : return response if response [ 'Code' ] in [ 101 , 201 ] : out . set_values ( { 'devid' : devid , 'wid' : wid , 'domain' : utils . Domain ( response [ 'Data' ] [ 'Domain' ] ) , 'uid' : uid } ) break if response [ 'Code' ] == 408 : if 'Field' not in response [ 'Data' ] : return RetVal ( ErrServerError , 'server sent 408 without telling what existed' ) if response [ 'Data' ] [ 'Field' ] not in [ 'User-ID' , 'Workspace-ID' ] : return RetVal ( ErrServerError , 'server sent bad 408 response' ) . set_value ( 'Field' , response [ 'Data' ] [ 'Field' ] ) if response [ 'Data' ] [ 'Field' ] == 'User-ID' : return RetVal ( ErrExists , 'user id' ) tries = tries + 1 wid . set ( '' ) else : return wrap_server_error ( response ) return out
Creates an account on the server.
Creates an account on the server .
'''Creates an account on the server.''' # This construct is a little strange, but it is to work around the minute possibility that # there is a WID collision, i.e. the WID generated by the client already exists on the server. # In such an event, it should try again. However, in the ridiculously small chance that the  # client keeps generating collisions, it should wait 3 seconds after 10 collisions to reduce  # server load. # Technically, the active profile already has a WID, but it is not attached to a domain and # doesn't matter as a result. Rather than adding complexity, we just generate a new UUID # and always return the replacement value # Pending, Success # WID or UID exists # Something we didn't expect -- reg closed, payment req'd, etc.
conn
ServerConnection
uid
utils.UserID
pwhash
str
devid
utils.UUID
devicekey
CryptoString