Django: Reimplementing Argon2PasswordHasher with key - django

In my Django project, I need to modify Argon2PasswordHasher to be able to encrypt with the key (SECRET_KEY) imported from settings.py.
I learned that key should be an optional parameter in Argon2, so I have to introduce it in this algorithm.
I tried to modify it including a key param in the params method but it didn't work.
How can I do?
class Argon2PasswordHasher(BasePasswordHasher):
Secure password hashing using the argon2 algorithm.
This is the winner of the Password Hashing Competition 2013-2015
(https://password-hashing.net). It requires the argon2-cffi library which
depends on native C code and might cause portability issues.
"""
algorithm = 'argon2'
library = 'argon2'
time_cost = 2
memory_cost = 102400
parallelism = 8
def encode(self, password, salt):
argon2 = self._load_library()
params = self.params()
data = argon2.low_level.hash_secret(
password.encode(),
salt.encode(),
time_cost=params.time_cost,
memory_cost=params.memory_cost,
parallelism=params.parallelism,
hash_len=params.hash_len,
type=params.type,
)
return self.algorithm + data.decode('ascii')
def decode(self, encoded):
argon2 = self._load_library()
algorithm, rest = encoded.split('$', 1)
assert algorithm == self.algorithm
params = argon2.extract_parameters('$' + rest)
variety, *_, b64salt, hash = rest.split('$')
# Add padding.
b64salt += '=' * (-len(b64salt) % 4)
salt = base64.b64decode(b64salt).decode('latin1')
return {
'algorithm': algorithm,
'hash': hash,
'memory_cost': params.memory_cost,
'parallelism': params.parallelism,
'salt': salt,
'time_cost': params.time_cost,
'variety': variety,
'version': params.version,
'params': params,
}
def verify(self, password, encoded):
argon2 = self._load_library()
algorithm, rest = encoded.split('$', 1)
assert algorithm == self.algorithm
try:
return argon2.PasswordHasher().verify('$' + rest, password)
except argon2.exceptions.VerificationError:
return False
def safe_summary(self, encoded):
decoded = self.decode(encoded)
return {
_('algorithm'): decoded['algorithm'],
_('variety'): decoded['variety'],
_('version'): decoded['version'],
_('memory cost'): decoded['memory_cost'],
_('time cost'): decoded['time_cost'],
_('parallelism'): decoded['parallelism'],
_('salt'): mask_hash(decoded['salt']),
_('hash'): mask_hash(decoded['hash']),
}
def must_update(self, encoded):
decoded = self.decode(encoded)
current_params = decoded['params']
new_params = self.params()
# Set salt_len to the salt_len of the current parameters because salt
# is explicitly passed to argon2.
new_params.salt_len = current_params.salt_len
update_salt = must_update_salt(decoded['salt'], self.salt_entropy)
return (current_params != new_params) or update_salt
def harden_runtime(self, password, encoded):
# The runtime for Argon2 is too complicated to implement a sensible
# hardening algorithm.
pass
def params(self):
argon2 = self._load_library()
# salt_len is a noop, because we provide our own salt.
return argon2.Parameters(
type=argon2.low_level.Type.ID,
version=argon2.low_level.ARGON2_VERSION,
salt_len=argon2.DEFAULT_RANDOM_SALT_LENGTH,
hash_len=argon2.DEFAULT_HASH_LENGTH,
time_cost=self.time_cost,
memory_cost=self.memory_cost,
parallelism=self.parallelism,
)

Related

list indices must be integers or slices, not dict in django

I just want to iterate through the list of JSON data which I get in the payload but getting an error as list indices must be integers or slices, not dict
payload:
[{"AuditorId":10,"Agents":"sa","Supervisor":"sa","TicketId":"58742","QId":150,"Answer":"Yes","TypeSelected":"CMT Mails","Comments":"na","TicketType":"Regularticket","Action":"na","AuditSubFunction":"na","AuditRegion":"na"},{"AuditorId":10,"Agents":"sa","Supervisor":"sa","TicketId":"58742","QId":151,"Answer":"Yes","TypeSelected":"CMT Mails","Comments":"na","TicketType":"Regularticket","Action":"na","AuditSubFunction":"na","AuditRegion":"na"}]
views.py:
#api_view(['POST'])
def SaveUserResponse(request):
for ran in request.data:
auditorid = request.data[ran].get('AuditorId')
ticketid = request.data[ran].get('TicketId')
qid = request.data[ran].get('QId')
answer = request.data[ran].get('Answer')
sid = '0'
TicketType = request.data[ran].get('TicketType')
TypeSelected = request.data[ran].get('TypeSelected')
agents = request.data[ran].get('Agents')
supervisor = request.data[ran].get('Supervisor')
Comments = request.data[ran].get('Comments')
action = request.data[ran].get('Action')
subfunction = request.data[ran].get('AuditSubFunction')
region = request.data[ran].get('AuditRegion')
cursor = connection.cursor()
cursor.execute('EXEC [dbo].[sp_SaveAuditResponse] #auditorid=%s,#ticketid=%s,#qid=%s,#answer=%s,#sid=%s,#TicketType=%s,#TypeSelected=%s,#agents=%s, #supervisor =%s, #Comments=%s, #action=%s, #subfunction=%s, #region=%s',
(auditorid,ticketid,qid,answer, sid,TicketType, TypeSelected, agents, supervisor, Comments, action, subfunction,region))
return Response(True)
I ran this code on my machine and it works for the payload you provided.
#api_view(['POST'])
def SaveUserResponse(request):
for ran in request.data:
auditorid = ran.get('AuditorId')
ticketid = ran.get('TicketId')
qid = ran.get('QId')
answer = ran.get('Answer')
sid = '0'
TicketType = ran.get('TicketType')
TypeSelected = ran.get('TypeSelected')
agents = ran.get('Agents')
supervisor = ran.get('Supervisor')
Comments = ran.get('Comments')
action = ran.get('Action')
subfunction = ran.get('AuditSubFunction')
region = ran.get('AuditRegion')
If it doesn't then content of request.data must be different then payload you shared in original post

unable to write test for django model containing custom model field

I have a model for users where in the field for password is a custom field. This model works fine but i'm not able to run tests for the model.
my model
from core_engine.CustomModelFields import *
class Users(models.Model):
username = models.EmailField(unique=True)
name = models.CharField(max_length=100)
password = EncryptedField(max_length=500)
in my core_engine.CustomModelFields.py file
from account_engine.crypto import *
class EncryptedField(CharField):
def from_db_value(self, value, expression, connection, context):
value = Password.decrypt(str(value))
return value.decode("utf-8")
def to_python(self, value):
if not value:
return None
return value
#Only need to decrypt if password already encrypted.
try:
if Password.encrypt(Password.decrypt(value)) == value:
value = Password.decrypt(str(value))
return value.decode("utf-8")
except:
return value
def get_db_prep_save(self, value, connection):
value = Password.encrypt(str(value))
return value
and finally in accounts_engine.crypto.py file i have
import base64, hashlib
from django.db import models
from Crypto import Random
from Crypto.Cipher import AES
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-s[-1]]
class Password(models.Model):
def encrypt( raw ):
mysecretpassword = 'somepassword'
KEY = hashlib.sha256(mysecretpassword.encode('utf-8')).digest()
raw = pad(raw)
iv = Random.new().read( AES.block_size )
cipher = AES.new( KEY, AES.MODE_CBC, iv )
return base64.b64encode( iv + cipher.encrypt( raw ) )
def decrypt( enc ):
mysecretpassword = 'somepassword'
KEY = hashlib.sha256(mysecretpassword.encode('utf-8')).digest()
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(KEY, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] ))
All i want to do is just test my Users model and see that i'm able to create a user during test, which will be required for other tests
so in my test.py file i have
class UsersTestCase(TestCase):
#classmethod
def setUp(self):
print(dt.datetime.now())
self.user= Users.objects.create(
username = 'test#test.com',
date_first_registered = dt.datetime.now(),
password = Password.encrypt('abc')
)
def test_get_user(self):
first_customer = Users.objects.first()
self.assertEqual(first_customer.username, 'test#test.com')
On running the above test, i get an error stating :
TypeError: Object type <class 'str'> cannot be passed to C code
Edit : i understand that the error is due to me passing the password as Password.encrypt('abc').
what changes should i make to my test function in order to create to create a new user
TRACEBACK
Traceback (most recent call last):
File "D:\project_path\account_engine\tests\tests_models.py", line 15, in setUp
password = Password.encrypt('abc')
File "D:\project_path\account_engine\crypto.py", line 21, in encrypt
return base64.b64encode( iv + cipher.encrypt( raw ) )
File "d:\project_path\venv\lib\site-packages\Crypto\Cipher\_mode_cbc.py", line 178, in encrypt
c_uint8_ptr(plaintext),
File "d:\project_path\venv\lib\site-packages\Crypto\Util\_raw_api.py", line 144, in c_uint8_ptr
raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type <class 'str'> cannot be passed to C code
Encrypt method accepts bytes string type and not str in Python 3:
Plaintexts and ciphertexts (input/output) can only be bytes, bytearray or memoryview. In Python 3, you cannot pass strings. In Python 2, you cannot pass Unicode strings.
You need to encode raw first:
def encrypt( raw ):
mysecretpassword = 'somepassword'
KEY = hashlib.sha256(mysecretpassword.encode('utf-8')).digest()
raw = pad(raw)
iv = Random.new().read( AES.block_size )
cipher = AES.new( KEY, AES.MODE_CBC, iv )
return base64.b64encode(iv + cipher.encrypt(raw.encode('utf-8')))

how to fix make_response error by adding mimetype to json data ty pe in Flask

I am trying to make slurm-web code working.
in restapi.py, there is a def sinfo() method which reads as follows:
#app.route('/sinfo', methods=['GET', 'OPTIONS'])
#crossdomain(origin=origins, methods=['GET'],
headers=['Accept', 'Content-Type', 'X-Requested-With', 'Authorization'])
#authentication_verify()
def sinfo():
# Partition and node lists are required
# to compute sinfo informations
partitions = get_from_cache(pyslurm.partition().get, 'get_partitions')
nodes = get_from_cache(pyslurm.node().get, 'get_nodes')
# Retreiving the state of each nodes
nodes_state = dict(
(node.lower(), attributes['state'].lower())
for node, attributes in nodes.iteritems()
)
# For all partitions, retrieving the states of each nodes
sinfo_data = {}
for name, attr in partitions.iteritems():
for node in list(NodeSet(attr['nodes'])):
key = (name, nodes_state[node])
if key not in sinfo_data.keys():
sinfo_data[key] = []
sinfo_data[key].append(node)
# Preparing the response
resp = []
for k, nodes in sinfo_data.iteritems():
name, state = k
partition = partitions[name]
avail = partition['state'].lower()
min_nodes = partition['min_nodes']
max_nodes = partition['max_nodes']
total_nodes = partition['total_nodes']
job_size = "{0}-{1}".format(min_nodes, max_nodes)
job_size = job_size.replace('UNLIMITED', 'infinite')
time_limit = partition['max_time_str'].replace('UNLIMITED', 'infinite')
# Creating the nodeset
nodeset = NodeSet()
map(nodeset.update, nodes)
resp.append({
'name': name,
'avail': avail,
'job_size': job_size,
'time_limit': time_limit,
'nodes': total_nodes,
'state': state,
'nodelist': str(nodeset),
})
# Jsonify can not works on list, thus using json.dumps
# And making sure headers are properly set
return make_response(json.dumps(resp), mimetype='application/json')
apache error log says that
return make_response(json.dumps(resp), mimetype='application/json')
TypeError: make_response() got an unexpected keyword argument 'mimetype'
I am using flase 1.0.2 and wondering what makes this error.
First, you'll need to indent that return so that it happens at the end of sinfo(). Then you can simplify by writing
from flask import jsonify
...
def sinfo():
...
return jsonify(resp)

python script to read and write a path to registry

I have developed a python script where i have a setting window which has the options to select the paths for the installation of software.When clicked on OK button of the setting window, i want to write all the selected paths to the registry and read the same when setting window is opened again.
My code looks as below.
def OnOk(self, event):
data1=self.field1.GetValue() #path selected in setting window
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
keyVal=OpenKey(aReg,r"SOFTWARE\my path to\Registry", 0,KEY_WRITE)
try:
SetValueEx(keyVal,"Log file",0,REG_SZ,data1)
except EnvironmentError:
pass
CloseKey(keyVal)
CloseKey(aReg)
I get a error like below:
Traceback (most recent call last):
File "D:\PROJECT\project.py", line 305, in OnOk
keyVal=OpenKey(aReg,r"SOFTWARE\my path to\Registry", 0,KEY_WRITE)
WindowsError: [Error 5] Access is denied
And to read from registry,the saved registry has to show up in the setting window.I tried with the below code.Though its working but not satisfied with the way i programmed it.Help me out for the better solution
key = OpenKey(HKEY_CURRENT_USER, r'Software\my path to\Registry', 0, KEY_READ)
for i in range(4):
try:
n,v,t = EnumValue(key,i)
if i==0:
self.field2.SetValue(v)
elif i==1:
self.field3.SetValue(v)
elif i==2:
self.field4.SetValue(v)
elif i==3:
self.field1.SetValue(v)
except EnvironmentError:
pass
CloseKey(key)
#Python3 version of hugo24's snippet
import winreg
REG_PATH = r"Control Panel\Mouse"
def set_reg(name, value):
try:
winreg.CreateKey(winreg.HKEY_CURRENT_USER, REG_PATH)
registry_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, REG_PATH, 0,
winreg.KEY_WRITE)
winreg.SetValueEx(registry_key, name, 0, winreg.REG_SZ, value)
winreg.CloseKey(registry_key)
return True
except WindowsError:
return False
def get_reg(name):
try:
registry_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, REG_PATH, 0,
winreg.KEY_READ)
value, regtype = winreg.QueryValueEx(registry_key, name)
winreg.CloseKey(registry_key)
return value
except WindowsError:
return None
#Example MouseSensitivity
#Read value
print (get_reg('MouseSensitivity'))
#Set Value 1/20 (will just write the value to reg, the changed mouse val requires a win re-log to apply*)
set_reg('MouseSensitivity', str(10))
#*For instant apply of SystemParameters like the mouse speed on-write, you can use win32gui/SPI
#http://docs.activestate.com/activepython/3.4/pywin32/win32gui__SystemParametersInfo_meth.html
Same as #Aramanethota but with pep8 and func def for easy usage.
REG_PATH = r"SOFTWARE\my_program\Settings"
def set_reg(name, value):
try:
_winreg.CreateKey(_winreg.HKEY_CURRENT_USER, REG_PATH)
registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0,
_winreg.KEY_WRITE)
_winreg.SetValueEx(registry_key, name, 0, _winreg.REG_SZ, value)
_winreg.CloseKey(registry_key)
return True
except WindowsError:
return False
def get_reg(name):
try:
registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0,
_winreg.KEY_READ)
value, regtype = _winreg.QueryValueEx(registry_key, name)
_winreg.CloseKey(registry_key)
return value
except WindowsError:
return None
Python script to read from registry is as follows:
try:
root_key=OpenKey(HKEY_CURRENT_USER, r'SOFTWARE\my path to\Registry', 0, KEY_READ)
[Pathname,regtype]=(QueryValueEx(root_key,"Pathname"))
CloseKey(root_key)
if (""==Pathname):
raise WindowsError
except WindowsError:
return [""]
Python script to write to the registry is:
try:
keyval=r"SOFTWARE\my path to\Registry"
if not os.path.exists("keyval"):
key = CreateKey(HKEY_CURRENT_USER,keyval)
Registrykey= OpenKey(HKEY_CURRENT_USER, r"SOFTWARE\my path to\Registry", 0,KEY_WRITE)
SetValueEx(Registrykey,"Pathname",0,REG_SZ,Pathname)
CloseKey(Registrykey)
return True
except WindowsError:
return False
Hope it helps you all.Cheers:)
Reading registry keys:
def read(path, root=HKEY_CURRENT_USER):
path, name = os.path.split(path)
with suppress(FileNotFoundError), OpenKey(root, path) as key:
return QueryValueEx(key, name)[0]
And writing:
def write(path, value, root=HKEY_CURRENT_USER):
path, name = os.path.split(path)
with OpenKey(root, path, 0, KEY_WRITE) as key:
SetValueEx(key, name, 0, REG_SZ, value)
Extended for type handling. Provide type as argument, match current type in registry or python value type.
def write(path, value, root=HKEY_CURRENT_USER, regtype=None):
path, name = os.path.split(path)
with OpenKey(root, path, 0, KEY_WRITE|KEY_READ) as key:
with suppress(FileNotFoundError):
regtype = regtype or QueryValueEx(key, name)[1]
SetValueEx(key, name, 0, regtype or REG_DWORD if isinstance(value, int) else REG_SZ, str(value) if regtype==REG_SZ else value)
NOTE: Use of contextlib.suppress() (available since python 3.4) can be replaced by try..except..pass for older versions. The context manager interface for winreg was introduced in python 2.6.
Looks like you don't have permission to edit the Registry. Incase if you are Admin, Please run this script in Elevated state.
Here is a class I wrote (python 2) which has the ability to restore state when you finish manipulating the registry. The class was not tested properly so it may contain some bugs:
import _winreg as winreg
class Registry(object):
def __init__(self, restore_state=False):
self.m_backup = {}
self.m_restore_state = restore_state
def get_key(self, hkey, subkey, access, create_if_doesnt_exist=True):
created_key = False
registry_key = None
try:
registry_key = winreg.OpenKey(hkey, subkey, 0, access)
except WindowsError:
try:
if create_if_doesnt_exist:
registry_key = winreg.CreateKey(hkey, subkey)
if registry_key not in self.m_backup:
self.m_backup[registry_key] = ({}, (hkey, subkey))
else:
registry_key = None
except WindowsError:
if registry_key:
self.close_key(registry_key)
raise Exception('Registry does not exist and could not be created.')
return registry_key
def close_key(self, registry_key):
closed = False
if registry_key:
try:
winreg.CloseKey(registry_key)
closed = True
except:
closed = False
return closed
def get_reg_value(self, hkey, subkey, name):
value = None
registry_key = self.get_key(hkey, subkey, winreg.KEY_READ, False)
if registry_key:
try:
value, _ = winreg.QueryValueEx(registry_key, name)
except WindowsError:
value = None
finally:
self.close_key(registry_key)
return value
def set_reg_value(self, hkey, subkey, name, type, value):
registry_key = self.get_key(hkey, subkey, winreg.KEY_WRITE, True)
backed_up = False
was_set = False
if registry_key:
if self.m_restore_state:
if registry_key not in self.m_backup:
self.m_backup[registry_key] = ({}, None)
existing_value = self.get_reg_value(hkey, subkey, name)
if existing_value:
self.m_backup[registry_key][0][name] = (existing_value, type, False)
else:
self.m_backup[registry_key][0][name] = (None, None, True)
backed_up = True
try:
winreg.SetValueEx(registry_key, name, 0, type, value)
was_set = True
except WindowsError:
was_set = False
finally:
if not backed_up:
self.close_key(registry_key)
return was_set
def restore_state(self):
if self.m_restore_state:
for registry_key, data in self.m_backup.iteritems():
backup_dict, key_info = data
try:
for name, backup_data in backup_dict.iteritems():
value, type, was_created = backup_data
if was_created:
print registry_key, name
winreg.DeleteValue(registry_key, name)
else:
winreg.SetValueEx(registry_key, name, 0, type, value)
if key_info:
hkey, subkey = key_info
winreg.DeleteKey(hkey, subkey)
except:
raise Exception('Could not restore value')
self.close_key(registry_key)
def __del__(self):
if self.m_restore_state:
self.restore_state()
for Creating / writing values in registry key:
from winreg import*
import winreg
keyVal = r'SOFTWARE\\python'
try:
key = OpenKey(HKEY_LOCAL_MACHINE, keyVal, 0, KEY_ALL_ACCESS)
except:
key = CreateKey(HKEY_LOCAL_MACHINE, keyVal)
SetValueEx(key, "Start Page", 0, REG_SZ, "snakes")
CloseKey(key)
If access denied - try running the command (CMd or IDE) in administrative mode
for reading value in registry-key
from winreg import*
Registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
RawKey = OpenKey(Registry, "SOFTWARE\\python")
try:
i = 0
while 1:
name, value, type = EnumValue(RawKey, i)
print("name:",name,"value:", value,"i:", i)
i += 1
except WindowsError:
print("")
My solution:
def add_key(name,pathh):
try:
keyval=r"System\my path\Register"
if not os.path.exists("keyval"):
key = winreg.CreateKey(winreg.HKEY_CURRENT_USER,keyval)
Registrykey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"System\my path\Register", 0,winreg.KEY_WRITE)
winreg.SetValueEx(Registrykey,name,1,winreg.REG_SZ,pathh)
winreg.CloseKey(Registrykey)
return True
except WindowsError:
return False
The 'winreg' module is so ...strange working module, so, I wrote a class called 'WindowsRegistry' for working with Windows registry and 'winreg' module easier. I hope it will be more usefull:
import winreg
import re
class WindowsRegistry:
"""Class WindowsRegistry is using for easy manipulating Windows registry.
Methods
-------
query_value(full_path : str)
Check value for existing.
get_value(full_path : str)
Get value's data.
set_value(full_path : str, value : str, value_type='REG_SZ' : str)
Create a new value with data or set data to an existing value.
delete_value(full_path : str)
Delete an existing value.
query_key(full_path : str)
Check key for existing.
delete_key(full_path : str)
Delete an existing key(only without subkeys).
Examples:
WindowsRegistry.set_value('HKCU/Software/Microsoft/Windows/CurrentVersion/Run', 'Program', r'"c:\Dir1\program.exe"')
WindowsRegistry.delete_value('HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run/Program')
"""
#staticmethod
def __parse_data(full_path):
full_path = re.sub(r'/', r'\\', full_path)
hive = re.sub(r'\\.*$', '', full_path)
if not hive:
raise ValueError('Invalid \'full_path\' param.')
if len(hive) <= 4:
if hive == 'HKLM':
hive = 'HKEY_LOCAL_MACHINE'
elif hive == 'HKCU':
hive = 'HKEY_CURRENT_USER'
elif hive == 'HKCR':
hive = 'HKEY_CLASSES_ROOT'
elif hive == 'HKU':
hive = 'HKEY_USERS'
reg_key = re.sub(r'^[A-Z_]*\\', '', full_path)
reg_key = re.sub(r'\\[^\\]+$', '', reg_key)
reg_value = re.sub(r'^.*\\', '', full_path)
return hive, reg_key, reg_value
#staticmethod
def query_value(full_path):
value_list = WindowsRegistry.__parse_data(full_path)
try:
opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_READ)
winreg.QueryValueEx(opened_key, value_list[2])
winreg.CloseKey(opened_key)
return True
except WindowsError:
return False
#staticmethod
def get_value(full_path):
value_list = WindowsRegistry.__parse_data(full_path)
try:
opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_READ)
value_of_value, value_type = winreg.QueryValueEx(opened_key, value_list[2])
winreg.CloseKey(opened_key)
return value_of_value
except WindowsError:
return None
#staticmethod
def set_value(full_path, value, value_type='REG_SZ'):
value_list = WindowsRegistry.__parse_data(full_path)
try:
winreg.CreateKey(getattr(winreg, value_list[0]), value_list[1])
opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_WRITE)
winreg.SetValueEx(opened_key, value_list[2], 0, getattr(winreg, value_type), value)
winreg.CloseKey(opened_key)
return True
except WindowsError:
return False
#staticmethod
def delete_value(full_path):
value_list = WindowsRegistry.__parse_data(full_path)
try:
opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_WRITE)
winreg.DeleteValue(opened_key, value_list[2])
winreg.CloseKey(opened_key)
return True
except WindowsError:
return False
#staticmethod
def query_key(full_path):
value_list = WindowsRegistry.__parse_data(full_path)
try:
opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1] + r'\\' + value_list[2], 0, winreg.KEY_READ)
winreg.CloseKey(opened_key)
return True
except WindowsError:
return False
#staticmethod
def delete_key(full_path):
value_list = WindowsRegistry.__parse_data(full_path)
try:
winreg.DeleteKey(getattr(winreg, value_list[0]), value_list[1] + r'\\' + value_list[2])
return True
except WindowsError:
return False

django: Class-based Form has no errors but is not valid. What is happening?

I have a form which is returning False from .is_valid(), but .errors and .non_field_errors() appear to be empty. Is there any other way to check out what might be causing this?
In case it's a problem with my logging code, here it is:
logger.debug('form.non_field_errors(): ' + str(form.non_field_errors()))
logger.debug('form.errors: ' + str(form.errors))
My form code:
class IncorporateForm(forms.Form):
type_choices = (("LTD", "Private company limited by shares"),
("LTG", "Private company limited by guarantee"),
("PLC", "Public limited company"),
("USC", "Unlimited company with share capital"),
("UWS", "Unlimited company without share capital"))
country_choices = (("EW", "England and Wales"),
("CY", "Wales"),
("SC", "Scotland"),
("NI", "Northern Ireland"))
articles_choices = (("MOD", "Model articles"),
("AMD", "Model articles with amendments"),
("BES", "Entirely bespoke articles"))
name = forms.CharField(initial = "[name] limited")
registered_office = forms.CharField(widget=forms.Textarea,
label='Registered office address')
registration_country = forms.ChoiceField(choices=country_choices,
widget=forms.RadioSelect(renderer=SaneRadioField))
company_type = forms.ChoiceField(choices=type_choices,
widget=forms.RadioSelect(renderer=SaneRadioField), initial="LTD")
articles_type = forms.ChoiceField(choices=articles_choices,
initial='MOD',
widget=forms.RadioSelect(renderer=SaneRadioField))
restricted_articles = forms.BooleanField()
arts_upload = forms.FileField(label='Articles to upload')
My view code (to the point where I detect that the form is not valid):
def incorporate_view(request):
form = IncorporateForm()
DirectorsFormset = forms.formsets.formset_factory(OfficerForm, extra=30)
CapitalFormset = forms.formsets.formset_factory(CapitalForm, extra=30)
HoldingFormset = forms.formsets.formset_factory(HoldingForm, extra=30)
AmendsFormset = forms.formsets.formset_factory(ArticlesAmendsForm, extra=50)
if request.method == 'POST':
#bind and validate
form.data = request.POST
guarantee_form = GuaranteeForm(data=request.POST)
directors_formset = DirectorsFormset(prefix='directors', data=request.POST)
capital_formset = CapitalFormset(prefix='capital', data=request.POST)
holding_formset = HoldingFormset(prefix='holding', data=request.POST)
amends_formset = AmendsFormset(prefix='amends', data=request.POST)
save_objects = [] # objects to be saved at the end if there is no error
user_objects = {} # keyed by email
individual_objects = {} # keyed by email?
if(not (form.is_valid() and guarantee_form.is_valid()
and directors_formset.is_valid()
and capital_formset.is_valid() and
holding_formset.is_valid() and
amends_formset.is_valid())):
dbg_str = """
form.is_valid(): %s
guarantee_form.is_valid(): %s
directors_formset.is_valid(): %s
capital_formset.is_valid(): %s
holding_formset.is_valid(): %s
amends_formset.is_valid(): %s
""" % (form.is_valid(), guarantee_form.is_valid(),
directors_formset.is_valid(),
capital_formset.is_valid(),
holding_formset.is_valid(),
amends_formset.is_valid())
logger.debug(dbg_str)
logger.debug('form.non_field_errors(): ' + str(form.non_field_errors()))
logger.debug('form.errors: ' + str(form.errors))
Assigning to form.data does not bind the form — you should pass the data dict when the object is constructed (or look into the code and see which flags are set, but that's probably not documented and therefore not recommended).