2013-08-22 03:39:41 -07:00
#!/usr/bin/env python
#
# Electrum - lightweight Bitcoin client
# Copyright (C) 2013 ecdsa@github
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from PyQt4 . QtGui import *
from PyQt4 . QtCore import *
2013-09-11 04:55:49 -07:00
from electrum . i18n import _
2013-09-24 07:57:12 -07:00
from util import *
2014-09-14 02:22:59 -07:00
import re
2013-08-22 03:39:41 -07:00
2014-07-10 12:44:28 -07:00
def make_password_dialog ( self , wallet , msg , new_pass = True ) :
2013-08-22 03:39:41 -07:00
2013-09-12 10:42:00 -07:00
self . pw = QLineEdit ( )
self . pw . setEchoMode ( 2 )
self . new_pw = QLineEdit ( )
self . new_pw . setEchoMode ( 2 )
self . conf_pw = QLineEdit ( )
self . conf_pw . setEchoMode ( 2 )
vbox = QVBoxLayout ( )
2013-09-13 05:16:13 -07:00
label = QLabel ( msg )
label . setWordWrap ( True )
2013-08-22 03:39:41 -07:00
2013-09-12 10:42:00 -07:00
grid = QGridLayout ( )
grid . setSpacing ( 8 )
2013-09-13 05:16:13 -07:00
grid . setColumnMinimumWidth ( 0 , 70 )
2013-09-13 04:56:33 -07:00
grid . setColumnStretch ( 1 , 1 )
2013-08-22 03:39:41 -07:00
2013-09-13 05:16:13 -07:00
logo = QLabel ( )
2014-04-21 13:09:15 -07:00
lockfile = " :icons/lock.png " if wallet and wallet . use_encryption else " :icons/unlock.png "
2013-09-13 05:16:13 -07:00
logo . setPixmap ( QPixmap ( lockfile ) . scaledToWidth ( 36 ) )
logo . setAlignment ( Qt . AlignCenter )
grid . addWidget ( logo , 0 , 0 )
grid . addWidget ( label , 0 , 1 , 1 , 2 )
vbox . addLayout ( grid )
grid = QGridLayout ( )
grid . setSpacing ( 8 )
grid . setColumnMinimumWidth ( 0 , 250 )
grid . setColumnStretch ( 1 , 1 )
2014-04-21 13:09:15 -07:00
if wallet and wallet . use_encryption :
2013-09-13 05:16:13 -07:00
grid . addWidget ( QLabel ( _ ( ' Password ' ) ) , 0 , 0 )
grid . addWidget ( self . pw , 0 , 1 )
2014-07-10 12:44:28 -07:00
2014-07-10 23:05:03 -07:00
grid . addWidget ( QLabel ( _ ( ' New Password ' ) if new_pass else _ ( ' Password ' ) ) , 1 , 0 )
2014-09-14 02:22:59 -07:00
self . password_help = HelpButton ( _ ( ' Password must be at least 6 characters ' ) + ' \n \n ' + _ ( ' It should contain a number, an uppercase alphabet and a special character ' ) )
2013-09-13 05:16:13 -07:00
grid . addWidget ( self . new_pw , 1 , 1 )
2014-09-14 02:22:59 -07:00
grid . addWidget ( self . password_help , 1 , 4 )
2013-08-22 03:39:41 -07:00
2013-09-13 05:16:13 -07:00
grid . addWidget ( QLabel ( _ ( ' Confirm Password ' ) ) , 2 , 0 )
grid . addWidget ( self . conf_pw , 2 , 1 )
2013-09-12 10:42:00 -07:00
vbox . addLayout ( grid )
2013-08-22 03:39:41 -07:00
2013-09-12 10:42:00 -07:00
vbox . addStretch ( 1 )
vbox . addLayout ( ok_cancel_buttons ( self ) )
2013-11-03 02:03:45 -08:00
return vbox
2013-08-22 03:39:41 -07:00
2013-09-12 10:42:00 -07:00
def run_password_dialog ( self , wallet , parent ) :
2014-05-01 09:58:24 -07:00
if wallet and wallet . is_watching_only ( ) :
2014-05-01 03:42:06 -07:00
QMessageBox . information ( parent , _ ( ' Error ' ) , _ ( ' This is a watching-only wallet ' ) , _ ( ' OK ' ) )
2013-12-13 08:30:34 -08:00
return False , None , None
2013-08-22 03:39:41 -07:00
2013-12-13 08:30:34 -08:00
if not self . exec_ ( ) :
return False , None , None
2013-09-12 10:42:00 -07:00
2014-04-21 13:09:15 -07:00
password = unicode ( self . pw . text ( ) ) if wallet and wallet . use_encryption else None
2013-09-12 10:42:00 -07:00
new_password = unicode ( self . new_pw . text ( ) )
new_password2 = unicode ( self . conf_pw . text ( ) )
if new_password != new_password2 :
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Passwords do not match ' ) , _ ( ' OK ' ) )
2013-10-07 09:47:36 -07:00
# Retry
2013-12-13 08:30:34 -08:00
return run_password_dialog ( self , wallet , parent )
2013-08-22 03:39:41 -07:00
2013-12-13 08:30:34 -08:00
if not new_password :
new_password = None
2014-09-14 02:22:59 -07:00
else :
#Check for password strength if user chooses to enter a password
#Check the length
if len ( new_password ) < 6 :
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Password is too short. It must be at least 6 characters ' ) + ' \n \n ' + _ ( ' Click help beside the password button for more information ' ) , _ ( ' OK ' ) )
# Retry
return run_password_dialog ( self , wallet , parent )
#Check for uppercase characters
if new_password . islower ( ) or new_password . isnumeric ( ) :
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Password must contain at least one Upper case alphabet ' ) + ' \n \n ' + _ ( ' Click help beside the password button for more information ' ) , _ ( ' OK ' ) )
# Retry
return run_password_dialog ( self , wallet , parent )
#Check for special characters
if ( re . match ( ' ^[a-zA-Z0-9]*$ ' , new_password ) ) :
QMessageBox . warning ( parent , _ ( ' Error ' ) , _ ( ' Password must contain at least one special character ' ) + ' \n \n ' + _ ( ' Click help beside the password button for more information ' ) , _ ( ' OK ' ) )
# Retry
return run_password_dialog ( self , wallet , parent )
2013-08-22 03:39:41 -07:00
2013-12-13 08:30:34 -08:00
return True , password , new_password
2013-08-22 03:39:41 -07:00
2013-09-12 10:42:00 -07:00
class PasswordDialog ( QDialog ) :
def __init__ ( self , wallet , parent ) :
QDialog . __init__ ( self , parent )
self . setModal ( 1 )
self . wallet = wallet
self . parent = parent
2014-03-25 15:08:23 -07:00
self . setWindowTitle ( _ ( " Set Password " ) )
2013-09-13 05:16:13 -07:00
msg = ( _ ( ' Your wallet is encrypted. Use this dialog to change your password. ' ) + ' ' \
2013-09-12 10:42:00 -07:00
+ _ ( ' To disable wallet encryption, enter an empty new password. ' ) ) \
if wallet . use_encryption else _ ( ' Your wallet keys are not encrypted ' )
2013-11-03 02:03:45 -08:00
self . setLayout ( make_password_dialog ( self , wallet , msg ) )
2013-09-12 10:42:00 -07:00
def run ( self ) :
2013-12-13 08:30:34 -08:00
ok , password , new_password = run_password_dialog ( self , self . wallet , self . parent )
if not ok :
return
try :
2014-05-01 03:42:06 -07:00
self . wallet . check_password ( password )
2013-12-13 08:30:34 -08:00
except Exception :
QMessageBox . warning ( self . parent , _ ( ' Error ' ) , _ ( ' Incorrect Password ' ) , _ ( ' OK ' ) )
return False , None , None
try :
self . wallet . update_password ( password , new_password )
except :
2014-05-04 10:43:15 -07:00
import traceback , sys
traceback . print_exc ( file = sys . stdout )
2013-12-13 08:30:34 -08:00
QMessageBox . warning ( self . parent , _ ( ' Error ' ) , _ ( ' Failed to update password ' ) , _ ( ' OK ' ) )
return
if new_password :
QMessageBox . information ( self . parent , _ ( ' Success ' ) , _ ( ' Password was updated successfully ' ) , _ ( ' OK ' ) )
else :
QMessageBox . information ( self . parent , _ ( ' Success ' ) , _ ( ' This wallet is not encrypted ' ) , _ ( ' OK ' ) )
2013-08-22 03:39:41 -07:00