comparison roundup/admin.py @ 7209:c1227f883177

Implement password hash testing using new roundup-admin perftest. Add new anypy/time_.py to provide a suitable definition for perf_counter for python2 or 3. Also update examples in upgrading.txt, man page, new translatable strings in locale.
author John Rouillard <rouilj@ieee.org>
date Fri, 03 Mar 2023 17:37:44 -0500
parents 65b12a9dd11c
children 07ce4e4110f5
comparison
equal deleted inserted replaced
7208:c9fa0ffb0f94 7209:c1227f883177
1745 else: 1745 else:
1746 print(_('No migration action required. At schema version %s.') % 1746 print(_('No migration action required. At schema version %s.') %
1747 self.db.database_schema['version']) 1747 self.db.database_schema['version'])
1748 return 0 1748 return 0
1749 1749
1750 def do_perftest(self, args):
1751 ''"""Usage: perftest [mode] [arguments]*
1752
1753 Time operations in Roundup. Supported arguments:
1754
1755 [password] [rounds=<integer>] [scheme=<scheme>]
1756
1757 'password' is the default mode. The tracker's config.ini
1758 setting for 'password_pbkdf2_default_rounds' is the default
1759 value for 'rounds'. On the command line, 'rounds' can include
1760 thousands separator of ',' or '.'. 'scheme' is the default
1761 coded into Roundup. List supported schemes by using 'scheme='.
1762
1763 """
1764 from roundup.anypy.time_ import perf_counter
1765
1766 props = { "rounds": self.db.config.PASSWORD_PBKDF2_DEFAULT_ROUNDS,
1767 "scheme": password.Password.known_schemes[0]
1768 }
1769
1770 print_supported_schemes = lambda: print(
1771 "Supported schemes (default is first, case "
1772 "sensitive):\n %s." %
1773 ", ".join(password.Password.known_schemes))
1774
1775 if (args[0].find("=") != -1):
1776 args.insert(0, 'password')
1777
1778 props.update(self.props_from_args(args[1:]))
1779
1780 if args[0] == "password":
1781 try:
1782 # convert 10,000,000 or 10.000.000 to 10000000
1783 r = int(re.sub('[,.]','',props['rounds']))
1784 if r < 1000:
1785 print(_("Invalid 'rounds'. Must be larger than 999."))
1786 return
1787 props['rounds'] = r
1788 except (TypeError, ValueError):
1789 print(_("Invalid 'rounds'. It must be an integer not: %s") %
1790 props['rounds'])
1791 return
1792 if props['scheme'] == None:
1793 print_supported_schemes()
1794 return
1795
1796 self.db.config.PASSWORD_PBKDF2_DEFAULT_ROUNDS = props['rounds']
1797
1798 try:
1799 tic = perf_counter()
1800 pw_hash = password.encodePassword(
1801 "this is a long password to hash",
1802 props['scheme'],
1803 None,
1804 config=self.db.config
1805 )
1806 toc = perf_counter()
1807 except password.PasswordValueError as e:
1808 print(e)
1809 print_supported_schemes()
1810 return
1811
1812 if props['scheme'].startswith('PBKDF2'):
1813 (rounds, salt, _raw_salt, digest) = password.pbkdf2_unpack(
1814 pw_hash)
1815 else:
1816 rounds = _("scheme does not support rounds.")
1817
1818 print(_(
1819 "Hash time: %(time)0.9f seconds, scheme: %(scheme)s, "
1820 "rounds: %(rounds)s") %
1821 { "time": toc-tic, "scheme": props['scheme'],
1822 "rounds": rounds})
1823
1750 def run_command(self, args): 1824 def run_command(self, args):
1751 """Run a single command 1825 """Run a single command
1752 """ 1826 """
1753 command = args[0] 1827 command = args[0]
1754 1828

Roundup Issue Tracker: http://roundup-tracker.org/