Source code for src.gui.login_dialog

# -*- coding: utf-8 -*-
# Copyright 2018 Ross Jacobs All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Login dialog GUI elements."""
from PyQt5.QtWidgets import QDialog

from src.dashboard_browser.dashboard_browser import DashboardBrowser
from src.gui.modal_dialogs import show_error_dialog
import src.gui.gui_setup as gui_setup


[docs]class LoginDialog(QDialog): """This class provides dialog GUI elements. Attributes: browser (MechanicalSoup): A browser in which to store user credentials. """ # Telling PyCharm linter not to (incorrectly) inspect PyQt function args # noinspection PyArgumentList def __init__(self): """Create UI vars necessary for login window to be shown.""" super(LoginDialog, self).__init__() self.browser = DashboardBrowser() self.tfa_success = False self.show_login()
[docs] def show_login(self): """Shows the login window and records if the login button is pressed. Uses methods stored in gui_setup to decorate the dialog object. If the login button is pressed, check whether the credentials are valid by sending them to the virtual browser. """ # Decorate login window with gui functions gui_setup.login_widget_setup(self) gui_setup.login_window_setup(self) gui_setup.login_set_layout(self) gui_setup.login_tfa_set_layout(self) self.show() self.login_btn.clicked.connect(self.check_login_attempt)
[docs] def get_login_info(self): """Returns the values currently in the user/pass text fields""" return self.username_field.text(), self.password_field.text()
[docs] def check_login_attempt(self): """Verifies whether entered username/password combination is correct NOTE: Keeping this code in here even though it is interface-independent. If we don't keep this here, then the login button will need to connect to self.close. It may look weird if the login window closes due to the user incorrectly entering user/pass and then reopens """ result = self.browser.attempt_login( self.username_field.text(), self.password_field.text() ) if result == 'auth_error': show_error_dialog('ERROR: Invalid username or password.') self.password_field.setText('') elif result == 'sms_auth': self.tfa_dialog_setup() self.close() elif result == 'auth_success': self.close() elif 'ConnectionError' in str(type(result)): show_error_dialog('ERROR: No internet connection!\n\nAccess to the ' 'internet is required for MerLink to work. ' 'Please check your network settings and try ' 'again. Now exiting...') exit() else: show_error_dialog("ERROR: Invalid authentication type!")
[docs] def tfa_dialog_setup(self): """Create and execute the UI for the TFA dialog""" # Create dialog window with login window object gui_setup.tfa_widget_setup(self) gui_setup.tfa_set_layout(self) self.yesbutton.clicked.connect(self.tfa_verify) self.nobutton.clicked.connect(self.twofactor_dialog.close) while not self.tfa_success: self.twofactor_dialog.exec_()
[docs] def tfa_verify(self): """Submit the tfa code and communicate success/failure to user. This fn is partially required because we need a function to connect to the button click signal. """ self.tfa_success = self.browser.tfa_submit_info( self.get_twofactor_code.text()) if self.tfa_success: self.twofactor_dialog.accept() else: show_error_dialog('ERROR: Invalid verification code!')