def encode_uri(ds_uri, schema_name, project_name=None): u = QUrl() urlQuery = QUrlQuery() u.setScheme("postgresql") u.setHost(ds_uri.host()) if ds_uri.port() != '': u.setPort(int(ds_uri.port())) if ds_uri.username() != '': u.setUserName(ds_uri.username()) if ds_uri.password() != '': u.setPassword(ds_uri.password()) if ds_uri.service() != '': urlQuery.addQueryItem("service", ds_uri.service()) if ds_uri.authConfigId() != '': urlQuery.addQueryItem("authcfg", ds_uri.authConfigId()) if ds_uri.sslMode() != QgsDataSourceUri.SslPrefer: urlQuery.addQueryItem("sslmode", QgsDataSourceUri.encodeSslMode(ds_uri.sslMode())) urlQuery.addQueryItem("dbname", ds_uri.database()) urlQuery.addQueryItem("schema", schema_name) if project_name: urlQuery.addQueryItem("project", project_name) u.setQuery(urlQuery) return str(u.toEncoded(), 'utf-8')
def processfile(self, i): print("processfile_start " + str(self.filecount - self.ui.listWidget.count())) if self.ui.listWidget.count() == 0: return file = str(self.ui.listWidget.item(i).text()) image = QImage(file) if self.ui.radio_noscale.isChecked(): pass elif self.ui.radio_both.isChecked(): image = image.scaled(self.ui.spin_width.value(), self.ui.spin_height.value(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation) elif self.ui.radio_width.isChecked(): w = self.ui.spin_width.value() image = image.scaledToWidth(w, Qt.KeepAspectRatio, Qt.SmoothTransformation) elif self.ui.radio_height.isChecked(): h = self.ui.spin_height.value() image = image.scaledToHeight(h, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.f = QTemporaryFile() self.f.open() image.save(self.f, 'JPG') self.f.seek(0) url = QUrl("ftp://" + self.ui.line_host.text() + "/" + self.ui.line_dir.text() + "/" + self.ui.line_prefix.text() + str(self.ui.spin_start_num.value()) + self.ui.line_suffix.text()) url.setUserName(self.ui.line_user.text()) url.setPassword(self.ui.line_pass.text()) url.setPort(self.ui.spin_port.value()) try: self.ui.listWidget.takeItem(0) self.ui.spin_start_num.setValue(self.ui.spin_start_num.value() + 1) self.nam = QNetworkAccessManager() self.rep = self.nam.put(QNetworkRequest(url), self.f) self.rep.finished.connect(self.isfinished) self.rep.error.connect(self.getError) if self.filecount != 0: self.progress = int( (self.filecount - self.ui.listWidget.count()) / (0.01 * self.filecount)) self.ui.progressBar.setValue(self.progress) except Exception as e: print("Exception " + str(e)) print("end")
def incdec_number(url, incdec, count=1, segments=None): """Find a number in the url and increment or decrement it. Args: url: The current url incdec: Either 'increment' or 'decrement' count: The number to increment or decrement by segments: A set of URL segments to search. Valid segments are: 'host', 'port', 'path', 'query', 'anchor'. Default: {'path', 'query'} Return: The new url with the number incremented/decremented. Raises IncDecError if the url contains no number. """ if not url.isValid(): raise InvalidUrlError(url) if segments is None: segments = {'path', 'query'} valid_segments = {'host', 'port', 'path', 'query', 'anchor'} if segments - valid_segments: extra_elements = segments - valid_segments raise IncDecError("Invalid segments: {}".format( ', '.join(extra_elements)), url) # Make a copy of the QUrl so we don't modify the original url = QUrl(url) # Order as they appear in a URL segment_modifiers = [ ('host', url.host, url.setHost), ('port', lambda: str(url.port()) if url.port() > 0 else '', lambda x: url.setPort(int(x))), ('path', url.path, url.setPath), ('query', url.query, url.setQuery), ('anchor', url.fragment, url.setFragment), ] # We're searching the last number so we walk the url segments backwards for segment, getter, setter in reversed(segment_modifiers): if segment not in segments: continue # Get the last number in a string match = re.fullmatch(r'(.*\D|^)(0*)(\d+)(.*)', getter()) if not match: continue setter(_get_incdec_value(match, incdec, url, count)) return url raise IncDecError("No number found in URL!", url)
def incdec_number(url, incdec, count=1, segments=None): """Find a number in the url and increment or decrement it. Args: url: The current url incdec: Either 'increment' or 'decrement' count: The number to increment or decrement by segments: A set of URL segments to search. Valid segments are: 'host', 'port', 'path', 'query', 'anchor'. Default: {'path', 'query'} Return: The new url with the number incremented/decremented. Raises IncDecError if the url contains no number. """ if not url.isValid(): raise InvalidUrlError(url) if segments is None: segments = {'path', 'query'} valid_segments = {'host', 'port', 'path', 'query', 'anchor'} if segments - valid_segments: extra_elements = segments - valid_segments raise IncDecError( "Invalid segments: {}".format(', '.join(extra_elements)), url) # Make a copy of the QUrl so we don't modify the original url = QUrl(url) # Order as they appear in a URL segment_modifiers = [ ('host', url.host, url.setHost), ('port', lambda: str(url.port()) if url.port() > 0 else '', lambda x: url.setPort(int(x))), ('path', url.path, url.setPath), ('query', url.query, url.setQuery), ('anchor', url.fragment, url.setFragment), ] # We're searching the last number so we walk the url segments backwards for segment, getter, setter in reversed(segment_modifiers): if segment not in segments: continue # Get the last number in a string match = re.fullmatch(r'(.*\D|^)(0*)(\d+)(.*)', getter()) if not match: continue setter(_get_incdec_value(match, incdec, url, count)) return url raise IncDecError("No number found in URL!", url)
class AuthWidget(QWebEngineView): def __init__(self, parent, config=None, credential_file=None, cookie_persistence=False, log_level=logging.INFO): super(AuthWidget, self).__init__(parent) self.parent = parent self.config = None self.config_file = DEFAULT_CONFIG_FILE self.credential = DEFAULT_CREDENTIAL self.credential_file = None self.cookie_file = None self.cookie_jar = None self.auth_url = None self.authn_session = None self.authn_session_page = None self.authn_cookie_name = None self.authn_expires = time.time() self._success_callback = None self._failure_callback = None self._session = requests.session() self.token = None self.default_profile = QWebEngineProfile("deriva-auth", self) self.private_profile = QWebEngineProfile(self) logging.getLogger().setLevel(log_level) info = "%s v%s [Python: %s (PyQt: %s), %s]" % ( self.__class__.__name__, get_installed_version(VERSION), platform.python_version(), PYQT_VERSION_STR, platform.platform(aliased=True)) logging.info("Initializing authorization provider: %s" % info) self.cookie_persistence = cookie_persistence self._timer = QTimer(self) self._timer.timeout.connect(self._onTimerFired) self.configure(config, credential_file) def configure(self, config, credential_file): self.config = config if config else read_config(self.config_file, create_default=True, default=DEFAULT_CONFIG) self.credential_file = credential_file host = self.config.get("host") if not host: self.set_current_html(ERROR_HTML % "Could not locate hostname parameter in configuration.") return self.auth_url = QUrl() self.auth_url.setScheme(config.get("protocol", "https")) self.auth_url.setHost(host) if config.get("port") is not None: self.auth_url.setPort(config["port"]) self.authn_cookie_name = self.config.get("cookie_name", "webauthn") self.cookie_file = DEFAULT_SESSION_CONFIG.get("cookie_jar") self.cookie_jar = load_cookies_from_file(self.cookie_file) retries = Retry(connect=DEFAULT_SESSION_CONFIG['retry_connect'], read=DEFAULT_SESSION_CONFIG['retry_read'], backoff_factor=DEFAULT_SESSION_CONFIG['retry_backoff_factor'], status_forcelist=DEFAULT_SESSION_CONFIG['retry_status_forcelist']) self._session.mount(self.auth_url.toString() + '/', HTTPAdapter(max_retries=retries)) def set_current_html(self, html): page = QWebEnginePage(self.parent) page.setHtml(html) self.setPage(page) self.update() qApp.processEvents() def authenticated(self): if self.authn_session is None: return False now = time.time() if now >= self.authn_expires: return False return True def login(self): if not (self.auth_url and (self.auth_url.host() and self.auth_url.scheme())): logging.error("Missing or invalid hostname parameter in configuration.") return logging.info("Authenticating with host: %s" % self.auth_url.toString()) qApp.setOverrideCursor(Qt.WaitCursor) self._cleanup() self.authn_session_page = QWebEnginePage(self.private_profile, self.parent) \ if not self.cookie_persistence else QWebEnginePage(self.default_profile, self.parent) self.authn_session_page.profile().setPersistentCookiesPolicy( QWebEngineProfile.ForcePersistentCookies if self.cookie_persistence else QWebEngineProfile.NoPersistentCookies) if self.cookie_persistence: logging.debug("QTWebEngine persistent storage located at: %s" % self.authn_session_page.profile().persistentStoragePath()) self.authn_session_page.profile().cookieStore().cookieAdded.connect(self._onCookieAdded) self.authn_session_page.profile().cookieStore().cookieRemoved.connect(self._onCookieRemoved) self.authn_session_page.loadProgress.connect(self._onLoadProgress) self.authn_session_page.loadFinished.connect(self._onLoadFinished) self.authn_session_page.setUrl(QUrl(self.auth_url.toString() + "/authn/preauth")) self.setPage(self.authn_session_page) def logout(self, delete_cookies=False): if not (self.auth_url and (self.auth_url.host() and self.auth_url.scheme())): return if self.authenticated(): try: logging.info("Logging out of host: %s" % self.auth_url.toString()) if delete_cookies and self.cookie_persistence: self.authn_session_page.profile().cookieStore().deleteAllCookies() self._session.delete(self.auth_url.toString() + "/authn/session") if self.credential_file: creds = read_credential(self.credential_file, create_default=True) host = self.auth_url.host() if creds.get(host): del creds[host] write_credential(self.credential_file, creds) except Exception as e: logging.warning("Logout error: %s" % format_exception(e)) self._cleanup() def setSuccessCallback(self, callback=None): self._success_callback = callback def setFailureCallback(self, callback=None): self._failure_callback = callback def setStatus(self, message): if self.window().statusBar is not None: self.window().statusBar().showMessage(message) def _execSuccessCallback(self): if self._success_callback: self._success_callback(host=self.auth_url.host(), credential=self.credential) def _execFailureCallback(self, message): if self._failure_callback: self._failure_callback(host=self.auth_url.host(), message=message) def _onTimerFired(self): if not self.authenticated(): self.authn_session = None return resp = self._session.put(self.auth_url.toString() + "/authn/session") seconds_remaining = self.authn_session['seconds_remaining'] self.authn_expires = time.time() + seconds_remaining + 1 if resp.ok: logging.trace("webauthn session:\n%s\n", resp.json()) logging.info("Session refreshed for: %s" % self.auth_url.host()) else: logging.warning( "Unable to refresh session for: %s. Server responded: %s" % (self.auth_url.host(), str.format("%s %s: %s" % (resp.status_code, resp.reason, resp.content.decode())))) def _onSessionContent(self, content): try: qApp.restoreOverrideCursor() self.set_current_html(SUCCESS_HTML) try: self.authn_session = json.loads(content) except json.JSONDecodeError: raise RuntimeError("Unable to parse response from server: %s" % content) seconds_remaining = self.authn_session['seconds_remaining'] if not self._timer.isActive(): interval = seconds_remaining // 2 logging.info("Authentication successful for [%s]: credential refresh in %d seconds." % (self.auth_url.toString(), interval)) self._timer.start(interval * 1000) self.authn_expires = time.time() + seconds_remaining + 1 logging.trace("webauthn session:\n%s\n", json.dumps(self.authn_session, indent=2)) QTimer.singleShot(100, self._execSuccessCallback) except (ValueError, Exception) as e: error = format_exception(e) logging.error(error) self.set_current_html(ERROR_HTML % content) self._execFailureCallback(error) def _onPreAuthContent(self, content): try: if not content: logging.debug("no preauth content") return preauth = json.loads(content) logging.trace("webauthn preauth:\n%s\n", json.dumps(preauth, indent=2)) qApp.setOverrideCursor(Qt.WaitCursor) self.authn_session_page.setUrl(QUrl(preauth["redirect_url"])) except (ValueError, Exception) as e: logging.error(format_exception(e)) self.set_current_html(ERROR_HTML % content) def _onLoadFinished(self, result): qApp.restoreOverrideCursor() qApp.processEvents() if not result: self.setPage(self.authn_session_page) logging.debug("Page load error: %s" % self.authn_session_page.url().toDisplayString()) return self.set_current_html(DEFAULT_HTML % self.auth_url.host()) path = self.authn_session_page.url().path() if path == "/authn/preauth": self.authn_session_page.toPlainText(self._onPreAuthContent) elif path == "/authn/session": self.authn_session_page.toPlainText(self._onSessionContent) else: if self.page() != self.authn_session_page: self.page().deleteLater() self.setPage(self.authn_session_page) def _onLoadProgress(self, progress): self.setStatus("Loading page: %s [%d%%]" % (self.page().url().host(), progress)) def _onCookieAdded(self, cookie): cookie_str = str(cookie.toRawForm(QNetworkCookie.NameAndValueOnly), encoding='utf-8') cookie_name = str(cookie.name(), encoding='utf-8') cookie_val = str(cookie.value(), encoding='utf-8') if (cookie_name == self.authn_cookie_name) and (cookie.domain() == self.config.get("host")): logging.trace("%s cookie added:\n\n%s\n\n" % (self.authn_cookie_name, cookie_str)) self.credential["cookie"] = "%s=%s" % (self.authn_cookie_name, cookie_val) host = self.auth_url.host() cred_entry = dict() cred_entry[host] = self.credential if self.credential_file: creds = read_credential(self.credential_file, create_default=True) creds.update(cred_entry) write_credential(self.credential_file, creds) self.token = cookie_val self._session.cookies.set(self.authn_cookie_name, cookie_val, domain=host, path='/') if self.cookie_jar is not None: self.cookie_jar.set_cookie( create_cookie(self.authn_cookie_name, cookie_val, domain=host, path='/', expires=0, discard=False, secure=True)) for path in self.config.get("cookie_jars", DEFAULT_CONFIG["cookie_jars"]): path_dir = os.path.dirname(path) if os.path.isdir(path_dir): logging.debug("Saving cookie jar to: %s" % path) self.cookie_jar.save(path, ignore_discard=True, ignore_expires=True) else: logging.debug("Cookie jar save path [%s] does not exist." % path_dir) def _onCookieRemoved(self, cookie): cookie_str = str(cookie.toRawForm(QNetworkCookie.NameAndValueOnly), encoding='utf-8') cookie_name = str(cookie.name(), encoding='utf-8') if cookie_name == self.authn_cookie_name and cookie.domain() == self.url().host(): logging.trace("%s cookie removed:\n\n%s\n\n" % (self.authn_cookie_name, cookie_str)) if self.cookie_jar: self.cookie_jar.clear(cookie_name, path=cookie.path(), domain=cookie.domain()) def _cleanup(self): self._timer.stop() self.token = None self.authn_session = None self.authn_expires = time.time() if self.authn_session_page: self.authn_session_page.loadProgress.disconnect(self._onLoadProgress) self.authn_session_page.loadFinished.disconnect(self._onLoadFinished) self.authn_session_page.profile().cookieStore().cookieAdded.disconnect(self._onCookieAdded) self.authn_session_page.profile().cookieStore().cookieRemoved.disconnect(self._onCookieRemoved) self.authn_session_page.deleteLater() self.authn_session_page = None