Merge pull request #1295 from pypeclub/feature/modules_using_keyring

Modules using keyring to store credentials
This commit is contained in:
Milan Kolar 2021-04-12 10:08:49 +02:00 committed by GitHub
commit 4e2ff4bd13
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 118 deletions

View file

@ -1,13 +1,16 @@
import os
import re
import time
import requests
import json
import datetime
import requests
from .constants import (
CLOCKIFY_ENDPOINT, ADMIN_PERMISSION_NAMES, CREDENTIALS_JSON_PATH
CLOCKIFY_ENDPOINT,
ADMIN_PERMISSION_NAMES
)
from openpype.lib.local_settings import OpenPypeSecureRegistry
def time_check(obj):
if obj.request_counter < 10:
@ -31,6 +34,8 @@ class ClockifyAPI:
self.request_counter = 0
self.request_time = time.time()
self.secure_registry = OpenPypeSecureRegistry("clockify")
@property
def headers(self):
return {"X-Api-Key": self.api_key}
@ -129,22 +134,10 @@ class ClockifyAPI:
return False
def get_api_key(self):
api_key = None
try:
file = open(CREDENTIALS_JSON_PATH, 'r')
api_key = json.load(file).get('api_key', None)
if api_key == '':
api_key = None
except Exception:
file = open(CREDENTIALS_JSON_PATH, 'w')
file.close()
return api_key
return self.secure_registry.get_item("api_key", None)
def save_api_key(self, api_key):
data = {'api_key': api_key}
file = open(CREDENTIALS_JSON_PATH, 'w')
file.write(json.dumps(data))
file.close()
self.secure_registry.set_item("api_key", api_key)
def get_workspaces(self):
action_url = 'workspaces/'

View file

@ -1,17 +1,12 @@
import os
import appdirs
CLOCKIFY_FTRACK_SERVER_PATH = os.path.join(
os.path.dirname(__file__), "ftrack", "server"
os.path.dirname(os.path.abspath(__file__)), "ftrack", "server"
)
CLOCKIFY_FTRACK_USER_PATH = os.path.join(
os.path.dirname(__file__), "ftrack", "user"
os.path.dirname(os.path.abspath(__file__)), "ftrack", "user"
)
CREDENTIALS_JSON_PATH = os.path.normpath(os.path.join(
appdirs.user_data_dir("pype-app", "pype"),
"clockify.json"
))
ADMIN_PERMISSION_NAMES = ["WORKSPACE_OWN", "WORKSPACE_ADMIN"]
CLOCKIFY_ENDPOINT = "https://api.clockify.me/api/"

View file

@ -210,3 +210,7 @@ class FtrackModule(
def tray_exit(self):
return self.tray_module.stop_action_server()
def set_credentials_to_env(self, username, api_key):
os.environ["FTRACK_API_USER"] = username or ""
os.environ["FTRACK_API_KEY"] = api_key or ""

View file

@ -1,23 +1,16 @@
import os
import json
import ftrack_api
import appdirs
import getpass
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
CONFIG_PATH = os.path.normpath(appdirs.user_data_dir("pype-app", "pype"))
CREDENTIALS_FILE_NAME = "ftrack_cred.json"
CREDENTIALS_PATH = os.path.join(CONFIG_PATH, CREDENTIALS_FILE_NAME)
CREDENTIALS_FOLDER = os.path.dirname(CREDENTIALS_PATH)
from openpype.lib import OpenPypeSecureRegistry
if not os.path.isdir(CREDENTIALS_FOLDER):
os.makedirs(CREDENTIALS_FOLDER)
USER_GETTER = None
USERNAME_KEY = "username"
API_KEY_KEY = "api_key"
def get_ftrack_hostname(ftrack_server=None):
@ -30,112 +23,73 @@ def get_ftrack_hostname(ftrack_server=None):
return urlparse(ftrack_server).hostname
def get_user():
if USER_GETTER:
return USER_GETTER()
return getpass.getuser()
def _get_ftrack_secure_key(hostname, key):
"""Secure item key for entered hostname."""
return "/".join(("ftrack", hostname, key))
def get_credentials(ftrack_server=None, user=None):
credentials = {}
if not os.path.exists(CREDENTIALS_PATH):
with open(CREDENTIALS_PATH, "w") as file:
file.write(json.dumps(credentials))
file.close()
return credentials
with open(CREDENTIALS_PATH, "r") as file:
content = file.read()
def get_credentials(ftrack_server=None):
hostname = get_ftrack_hostname(ftrack_server)
if not user:
user = get_user()
username_name = _get_ftrack_secure_key(hostname, USERNAME_KEY)
api_key_name = _get_ftrack_secure_key(hostname, API_KEY_KEY)
content_json = json.loads(content or "{}")
credentials = content_json.get(hostname, {}).get(user) or {}
username_registry = OpenPypeSecureRegistry(username_name)
api_key_registry = OpenPypeSecureRegistry(api_key_name)
return credentials
def save_credentials(ft_user, ft_api_key, ftrack_server=None, user=None):
hostname = get_ftrack_hostname(ftrack_server)
if not user:
user = get_user()
with open(CREDENTIALS_PATH, "r") as file:
content = file.read()
content_json = json.loads(content or "{}")
if hostname not in content_json:
content_json[hostname] = {}
content_json[hostname][user] = {
"username": ft_user,
"api_key": ft_api_key
return {
USERNAME_KEY: username_registry.get_item(USERNAME_KEY, None),
API_KEY_KEY: api_key_registry.get_item(API_KEY_KEY, None)
}
# Deprecated keys
if "username" in content_json:
content_json.pop("username")
if "apiKey" in content_json:
content_json.pop("apiKey")
with open(CREDENTIALS_PATH, "w") as file:
file.write(json.dumps(content_json, indent=4))
def clear_credentials(ft_user=None, ftrack_server=None, user=None):
if not ft_user:
ft_user = os.environ.get("FTRACK_API_USER")
if not ft_user:
return
def save_credentials(username, api_key, ftrack_server=None):
hostname = get_ftrack_hostname(ftrack_server)
if not user:
user = get_user()
username_name = _get_ftrack_secure_key(hostname, USERNAME_KEY)
api_key_name = _get_ftrack_secure_key(hostname, API_KEY_KEY)
with open(CREDENTIALS_PATH, "r") as file:
content = file.read()
# Clear credentials
clear_credentials(ftrack_server)
content_json = json.loads(content or "{}")
if hostname not in content_json:
content_json[hostname] = {}
username_registry = OpenPypeSecureRegistry(username_name)
api_key_registry = OpenPypeSecureRegistry(api_key_name)
content_json[hostname].pop(user, None)
with open(CREDENTIALS_PATH, "w") as file:
file.write(json.dumps(content_json))
username_registry.set_item(USERNAME_KEY, username)
api_key_registry.set_item(API_KEY_KEY, api_key)
def set_env(ft_user=None, ft_api_key=None):
os.environ["FTRACK_API_USER"] = ft_user or ""
os.environ["FTRACK_API_KEY"] = ft_api_key or ""
def clear_credentials(ftrack_server=None):
hostname = get_ftrack_hostname(ftrack_server)
username_name = _get_ftrack_secure_key(hostname, USERNAME_KEY)
api_key_name = _get_ftrack_secure_key(hostname, API_KEY_KEY)
username_registry = OpenPypeSecureRegistry(username_name)
api_key_registry = OpenPypeSecureRegistry(api_key_name)
current_username = username_registry.get_item(USERNAME_KEY, None)
current_api_key = api_key_registry.get_item(API_KEY_KEY, None)
if current_username is not None:
username_registry.delete_item(USERNAME_KEY)
if current_api_key is not None:
api_key_registry.delete_item(API_KEY_KEY)
def get_env_credentials():
return (
os.environ.get("FTRACK_API_USER"),
os.environ.get("FTRACK_API_KEY")
)
def check_credentials(ft_user, ft_api_key, ftrack_server=None):
def check_credentials(username, api_key, ftrack_server=None):
if not ftrack_server:
ftrack_server = os.environ["FTRACK_SERVER"]
if not ft_user or not ft_api_key:
if not username or not api_key:
return False
try:
session = ftrack_api.Session(
server_url=ftrack_server,
api_key=ft_api_key,
api_user=ft_user
api_key=api_key,
api_user=username
)
session.close()
except Exception:
return False
return True

View file

@ -30,7 +30,7 @@ class FtrackTrayWrapper:
self.bool_action_thread_running = False
self.bool_timer_event = False
self.widget_login = login_dialog.CredentialsDialog()
self.widget_login = login_dialog.CredentialsDialog(module)
self.widget_login.login_changed.connect(self.on_login_change)
self.widget_login.logout_signal.connect(self.on_logout)
@ -56,7 +56,7 @@ class FtrackTrayWrapper:
validation = credentials.check_credentials(ft_user, ft_api_key)
if validation:
self.widget_login.set_credentials(ft_user, ft_api_key)
credentials.set_env(ft_user, ft_api_key)
self.module.set_credentials_to_env(ft_user, ft_api_key)
log.info("Connected to Ftrack successfully")
self.on_login_change()
@ -337,7 +337,7 @@ class FtrackTrayWrapper:
def changed_user(self):
self.stop_action_server()
credentials.set_env()
self.module.set_credentials_to_env(None, None)
self.validate()
def start_timer_manager(self, data):

View file

@ -14,11 +14,13 @@ class CredentialsDialog(QtWidgets.QDialog):
login_changed = QtCore.Signal()
logout_signal = QtCore.Signal()
def __init__(self, parent=None):
def __init__(self, module, parent=None):
super(CredentialsDialog, self).__init__(parent)
self.setWindowTitle("OpenPype - Ftrack Login")
self._module = module
self._login_server_thread = None
self._is_logged = False
self._in_advance_mode = False
@ -268,7 +270,7 @@ class CredentialsDialog(QtWidgets.QDialog):
verification = credentials.check_credentials(username, api_key)
if verification:
credentials.save_credentials(username, api_key, False)
credentials.set_env(username, api_key)
self._module.set_credentials_to_env(username, api_key)
self.set_credentials(username, api_key)
self.login_changed.emit()
return verification