<s> import datetime <EOL> import hashlib <EOL> import json <EOL> import logging <EOL> import os <EOL> import re <EOL> import tempfile <EOL> import time <EOL> import urllib <EOL> from google . appengine . api import SOAPpy <EOL> from google . appengine . api . appcontroller_client import AppControllerClient <EOL> from google . appengine . api import users <EOL> from custom_exceptions import BadConfigurationException <EOL> from local_state import LocalState <EOL> from secret_key import GLOBAL_SECRET_KEY <EOL> from local_host import MY_PUBLIC_IP <EOL> from uaserver_host import UA_SERVER_IP <EOL> class AppHelperException ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class AppUploadStatuses ( object ) : <EOL> """<STR_LIT>""" <EOL> ID_NOT_FOUND = '<STR_LIT>' <EOL> STARTING = '<STR_LIT>' <EOL> COMPLETE = '<STR_LIT:true>' <EOL> class AppDashboardHelper ( object ) : <EOL> """<STR_LIT>""" <EOL> DEV_APPSERVER_LOGIN_COOKIE = '<STR_LIT>' <EOL> LOGIN_COOKIE_FIELD_SEPARATOR = '<STR_LIT::>' <EOL> LOGIN_COOKIE_APPS_SEPARATOR = '<STR_LIT:U+002C>' <EOL> LOGIN_COOKIE_APPS_PART = <NUM_LIT:2> <EOL> UA_SERVER_PORT = <NUM_LIT> <EOL> APP_DELIMITER = "<STR_LIT::>" <EOL> USER_DELIMITER = "<STR_LIT::>" <EOL> USER_CAPABILITIES_DELIMITER = '<STR_LIT::>' <EOL> USER_APP_LIST_REGEX = "<STR_LIT>" <EOL> CLOUD_ADMIN_REGEX = "<STR_LIT>" <EOL> USERNAME_FROM_EMAIL_REGEX = '<STR_LIT>' <EOL> USER_DATA_PASSWORD_REGEX = '<STR_LIT>' <EOL> ALL_USERS_NON_USER_REGEX = '<STR_LIT>' <EOL> TOKEN_EXPIRATION = "<STR_LIT>" <EOL> USE_SHIBBOLETH = False <EOL> SHIBBOLETH_CONNECTOR = '<STR_LIT>' <EOL> SHIBBOLETH_COOKIE_DOMAIN = '<STR_LIT>' <EOL> SHIBBOLETH_CONNECTOR_PORT = '<STR_LIT>' <EOL> SHIBBOLETH_LOGOUT_URL = SHIBBOLETH_CONNECTOR + '<STR_LIT>' <EOL> APP_UPLOAD_CHECK_INTERVAL = <NUM_LIT:1> <EOL> def __init__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . appcontroller = None <EOL> self . uaserver = None <EOL> self . cache = { <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : { } , <EOL> '<STR_LIT>' : { } <EOL> } <EOL> def get_appcontroller_client ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . appcontroller is None : <EOL> self . appcontroller = AppControllerClient ( MY_PUBLIC_IP , GLOBAL_SECRET_KEY ) <EOL> return self . appcontroller <EOL> def get_uaserver ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . uaserver is None : <EOL> self . uaserver = SOAPpy . SOAPProxy ( '<STR_LIT>' . format ( UA_SERVER_IP , <EOL> self . UA_SERVER_PORT ) ) <EOL> return self . uaserver <EOL> def get_user_capabilities ( self , email ) : <EOL> """<STR_LIT>""" <EOL> if email in self . cache [ '<STR_LIT>' ] : <EOL> return self . cache [ '<STR_LIT>' ] [ email ] <EOL> try : <EOL> capabilities = self . get_uaserver ( ) . get_capabilities ( email , <EOL> GLOBAL_SECRET_KEY ) . split ( self . USER_CAPABILITIES_DELIMITER ) <EOL> self . cache [ '<STR_LIT>' ] [ email ] = capabilities <EOL> return capabilities <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return [ ] <EOL> def get_status_info ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> status_info = self . get_appcontroller_client ( ) . get_stats ( ) <EOL> if status_info == True : <EOL> return [ ] <EOL> else : <EOL> return status_info <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return [ ] <EOL> def get_host_with_role ( self , role ) : <EOL> """<STR_LIT>""" <EOL> acc = self . get_appcontroller_client ( ) <EOL> if self . cache [ '<STR_LIT>' ] : <EOL> nodes = self . cache [ '<STR_LIT>' ] <EOL> else : <EOL> try : <EOL> nodes = acc . get_role_info ( ) <EOL> self . cache [ '<STR_LIT>' ] = nodes <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return '<STR_LIT>' <EOL> for node in nodes : <EOL> if role in node [ '<STR_LIT>' ] : <EOL> return node [ '<STR_LIT>' ] <EOL> return '<STR_LIT>' <EOL> def get_head_node_ip ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . get_host_with_role ( '<STR_LIT>' ) <EOL> def get_login_host ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . get_host_with_role ( '<STR_LIT>' ) <EOL> def get_app_ports ( self , appname ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> app_data = self . get_uaserver ( ) . get_app_data ( appname , GLOBAL_SECRET_KEY ) <EOL> result = json . loads ( app_data ) <EOL> if result : <EOL> return [ int ( result [ '<STR_LIT>' ] . values ( ) [ <NUM_LIT:0> ] [ '<STR_LIT:http>' ] ) , <EOL> int ( result [ '<STR_LIT>' ] . values ( ) [ <NUM_LIT:0> ] [ '<STR_LIT>' ] ) ] <EOL> else : <EOL> raise AppHelperException ( "<STR_LIT>" "<STR_LIT>" . format ( appname ) ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> raise AppHelperException ( "<STR_LIT>" "<STR_LIT>" . format ( appname ) ) <EOL> def shell_check ( self , argument ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' in argument : <EOL> raise BadConfigurationException ( "<STR_LIT>" + "<STR_LIT>" ) <EOL> def upload_app ( self , filename , upload_file ) : <EOL> """<STR_LIT>""" <EOL> user = users . get_current_user ( ) <EOL> if not user : <EOL> raise AppHelperException ( "<STR_LIT>" "<STR_LIT>" ) <EOL> try : <EOL> self . shell_check ( filename ) <EOL> file_suffix = re . search ( "<STR_LIT>" , filename ) . group ( <NUM_LIT:1> ) <EOL> acc = self . get_appcontroller_client ( ) <EOL> tgz_file = tempfile . NamedTemporaryFile ( suffix = file_suffix , delete = False ) <EOL> tgz_file . write ( upload_file . read ( ) ) <EOL> tgz_file . close ( ) <EOL> upload_info = acc . upload_app ( tgz_file . name , file_suffix , user . email ( ) ) <EOL> status = upload_info [ '<STR_LIT:status>' ] <EOL> while status == AppUploadStatuses . STARTING : <EOL> time . sleep ( self . APP_UPLOAD_CHECK_INTERVAL ) <EOL> status = acc . get_app_upload_status ( upload_info [ '<STR_LIT>' ] ) <EOL> if status == AppUploadStatuses . ID_NOT_FOUND : <EOL> os . remove ( '<STR_LIT>' . format ( tgz_file . name , file_suffix ) ) <EOL> raise AppHelperException ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if status == AppUploadStatuses . COMPLETE : <EOL> os . remove ( '<STR_LIT>' . format ( tgz_file . name , file_suffix ) ) <EOL> return '<STR_LIT>' '<STR_LIT>' <EOL> os . remove ( '<STR_LIT>' . format ( tgz_file . name , file_suffix ) ) <EOL> raise AppHelperException ( '<STR_LIT>' <EOL> . format ( status ) ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> match_data = re . search ( "<STR_LIT>" , str ( err ) ) <EOL> if match_data : <EOL> failure_message = match_data . group ( <NUM_LIT:1> ) <EOL> else : <EOL> failure_message = str ( err ) <EOL> raise AppHelperException ( "<STR_LIT>" <EOL> "<STR_LIT>" . format ( failure_message ) ) <EOL> def delete_app ( self , appname ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if not self . does_app_exist ( appname ) : <EOL> return "<STR_LIT>" <EOL> acc = self . get_appcontroller_client ( ) <EOL> ret = acc . stop_app ( appname ) <EOL> if ret != "<STR_LIT:true>" : <EOL> logging . error ( "<STR_LIT>" . format ( ret ) ) <EOL> return "<STR_LIT>" <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return "<STR_LIT>" <EOL> return "<STR_LIT>" + "<STR_LIT>" <EOL> def does_app_exist ( self , appname ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> result = self . get_uaserver ( ) . does_app_exists ( appname , GLOBAL_SECRET_KEY ) <EOL> if search_data : <EOL> num_ports = int ( search_data . group ( <NUM_LIT:1> ) ) <EOL> return num_ports > <NUM_LIT:0> <EOL> else : <EOL> return False <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return False <EOL> def is_user_logged_in ( self ) : <EOL> """<STR_LIT>""" <EOL> return users . get_current_user ( ) != None <EOL> def get_user_email ( self ) : <EOL> """<STR_LIT>""" <EOL> user = users . get_current_user ( ) <EOL> if user : <EOL> return user . email ( ) <EOL> else : <EOL> return '<STR_LIT>' <EOL> def get_owned_apps ( self , email = None ) : <EOL> """<STR_LIT>""" <EOL> if email is None : <EOL> user = users . get_current_user ( ) <EOL> if not user : <EOL> return [ ] <EOL> email = user . email ( ) <EOL> user_data = self . query_user_data ( email ) <EOL> user_data_match = re . search ( self . USER_APP_LIST_REGEX , user_data ) <EOL> if user_data_match : <EOL> return user_data_match . group ( <NUM_LIT:1> ) . split ( self . APP_DELIMITER ) <EOL> return [ ] <EOL> def query_user_data ( self , email ) : <EOL> """<STR_LIT>""" <EOL> if email in self . cache [ '<STR_LIT>' ] : <EOL> return self . cache [ '<STR_LIT>' ] [ email ] <EOL> try : <EOL> user_data = self . get_uaserver ( ) . get_user_data ( email , GLOBAL_SECRET_KEY ) <EOL> self . cache [ '<STR_LIT>' ] [ email ] = user_data <EOL> return user_data <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return '<STR_LIT>' <EOL> def is_user_cloud_admin ( self , email = None ) : <EOL> """<STR_LIT>""" <EOL> if email is None : <EOL> user = users . get_current_user ( ) <EOL> if not user : <EOL> return False <EOL> email = user . email ( ) <EOL> user_data = self . query_user_data ( email ) <EOL> if re . search ( self . CLOUD_ADMIN_REGEX , user_data ) : <EOL> return True <EOL> else : <EOL> return False <EOL> def can_upload_apps ( self , email = None ) : <EOL> """<STR_LIT>""" <EOL> if email is None : <EOL> user = users . get_current_user ( ) <EOL> if not user : <EOL> return False <EOL> email = user . email ( ) <EOL> return '<STR_LIT>' in self . get_user_capabilities ( email ) <EOL> def create_new_user ( self , email , password , response , <EOL> account_type = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> uaserver = self . get_uaserver ( ) <EOL> encrypted_pass = LocalState . encrypt_password ( email , password ) <EOL> result = uaserver . commit_new_user ( email , encrypted_pass , account_type , <EOL> GLOBAL_SECRET_KEY ) <EOL> if result != '<STR_LIT:true>' : <EOL> raise AppHelperException ( result ) <EOL> username_regex = re . compile ( self . USERNAME_FROM_EMAIL_REGEX ) <EOL> username = username_regex . match ( email ) . groups ( ) [ <NUM_LIT:0> ] <EOL> xmpp_user = "<STR_LIT>" . format ( username , <EOL> self . get_login_host ( ) ) <EOL> xmpp_pass = LocalState . encrypt_password ( xmpp_user , password ) <EOL> result = uaserver . commit_new_user ( xmpp_user , xmpp_pass , account_type , <EOL> GLOBAL_SECRET_KEY ) <EOL> if result != '<STR_LIT:true>' : <EOL> raise AppHelperException ( result ) <EOL> self . create_token ( email , email ) <EOL> self . set_appserver_cookie ( email , self . get_user_app_list ( email ) , response ) <EOL> except AppHelperException as err : <EOL> logging . exception ( err ) <EOL> raise AppHelperException ( str ( err ) ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> raise AppHelperException ( str ( err ) ) <EOL> return True <EOL> def get_user_app_list ( self , email ) : <EOL> """<STR_LIT>""" <EOL> user_data = self . query_user_data ( email ) <EOL> app_re = re . search ( self . USER_APP_LIST_REGEX , user_data ) <EOL> if app_re : <EOL> apps_list = app_re . group ( <NUM_LIT:1> ) . split ( self . APP_DELIMITER ) <EOL> return apps_list <EOL> return [ ] <EOL> def set_appserver_cookie ( self , email , apps_list , response ) : <EOL> """<STR_LIT>""" <EOL> apps = self . LOGIN_COOKIE_APPS_SEPARATOR . join ( apps_list ) <EOL> if AppDashboardHelper . USE_SHIBBOLETH : <EOL> response . set_cookie ( self . DEV_APPSERVER_LOGIN_COOKIE , <EOL> value = self . get_cookie_value ( email , apps ) , <EOL> domain = AppDashboardHelper . SHIBBOLETH_COOKIE_DOMAIN , <EOL> expires = datetime . datetime . now ( ) + datetime . timedelta ( days = <NUM_LIT:1> ) ) <EOL> else : <EOL> response . set_cookie ( self . DEV_APPSERVER_LOGIN_COOKIE , <EOL> value = self . get_cookie_value ( email , apps ) , <EOL> expires = datetime . datetime . now ( ) + datetime . timedelta ( days = <NUM_LIT:1> ) ) <EOL> def get_cookie_app_list ( self , request ) : <EOL> """<STR_LIT>""" <EOL> if self . DEV_APPSERVER_LOGIN_COOKIE in request . cookies : <EOL> cookie_value = urllib . unquote ( <EOL> request . cookies [ self . DEV_APPSERVER_LOGIN_COOKIE ] ) <EOL> if cookie_value : <EOL> cookie_parts = cookie_value . split ( self . LOGIN_COOKIE_FIELD_SEPARATOR ) <EOL> if len ( cookie_parts ) > self . LOGIN_COOKIE_APPS_PART : <EOL> return cookie_parts [ self . LOGIN_COOKIE_APPS_PART ] . split ( <EOL> self . LOGIN_COOKIE_APPS_SEPARATOR ) <EOL> return [ ] <EOL> def update_cookie_app_list ( self , owned_apps , request , response ) : <EOL> """<STR_LIT>""" <EOL> user = users . get_current_user ( ) <EOL> if not user : <EOL> return <EOL> email = user . email ( ) <EOL> cookie_apps = self . get_cookie_app_list ( request ) <EOL> if set ( owned_apps ) != set ( cookie_apps ) : <EOL> self . set_appserver_cookie ( email , owned_apps , response ) <EOL> return True <EOL> else : <EOL> return False <EOL> def get_cookie_value ( self , email , apps ) : <EOL> """<STR_LIT>""" <EOL> nick = re . search ( '<STR_LIT>' , email ) . group ( <NUM_LIT:1> ) <EOL> hsh = self . get_appengine_hash ( email , nick , apps ) <EOL> return urllib . quote ( "<STR_LIT>" . format ( <EOL> self . LOGIN_COOKIE_FIELD_SEPARATOR , email , nick , apps , hsh ) ) <EOL> def get_appengine_hash ( self , email , nick , apps ) : <EOL> """<STR_LIT>""" <EOL> return hashlib . sha1 ( "<STR_LIT>" . format ( email , nick , apps , <EOL> GLOBAL_SECRET_KEY ) ) . hexdigest ( ) <EOL> def create_token ( self , token , email ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> uaserver = self . get_uaserver ( ) <EOL> uaserver . commit_new_token ( token , email , self . TOKEN_EXPIRATION , <EOL> GLOBAL_SECRET_KEY ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> def logout_user ( self , response ) : <EOL> """<STR_LIT>""" <EOL> user = users . get_current_user ( ) <EOL> if user : <EOL> self . create_token ( '<STR_LIT>' , user . email ( ) ) <EOL> if AppDashboardHelper . USE_SHIBBOLETH : <EOL> response . delete_cookie ( self . DEV_APPSERVER_LOGIN_COOKIE , <EOL> domain = AppDashboardHelper . SHIBBOLETH_COOKIE_DOMAIN ) <EOL> else : <EOL> response . delete_cookie ( self . DEV_APPSERVER_LOGIN_COOKIE ) <EOL> def login_user ( self , email , password , response ) : <EOL> """<STR_LIT>""" <EOL> user_data = self . query_user_data ( email ) <EOL> server_re = re . search ( self . USER_DATA_PASSWORD_REGEX , user_data ) <EOL> if not server_re : <EOL> logging . error ( "<STR_LIT>" . format ( email ) ) <EOL> return False <EOL> server_pwd = server_re . group ( <NUM_LIT:1> ) <EOL> encrypted_pass = LocalState . encrypt_password ( email , password ) <EOL> if server_pwd != encrypted_pass : <EOL> logging . info ( "<STR_LIT>" . format ( email ) ) <EOL> return False <EOL> self . create_token ( email , email ) <EOL> self . set_appserver_cookie ( email , self . get_user_app_list ( email ) , response ) <EOL> return True <EOL> def list_all_users ( self ) : <EOL> """<STR_LIT>""" <EOL> ret_list = [ ] <EOL> try : <EOL> uas = self . get_uaserver ( ) <EOL> all_users = uas . get_all_users ( GLOBAL_SECRET_KEY ) <EOL> all_users_list = all_users . split ( self . USER_DELIMITER ) <EOL> my_ip = self . get_head_node_ip ( ) <EOL> for usr in all_users_list : <EOL> if re . search ( '<STR_LIT:@>' + my_ip + '<STR_LIT:$>' , usr ) : <EOL> continue <EOL> if re . search ( self . ALL_USERS_NON_USER_REGEX , usr ) : <EOL> continue <EOL> ret_list . append ( usr ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return ret_list <EOL> def list_all_users_permissions ( self ) : <EOL> """<STR_LIT>""" <EOL> ret_list = [ ] <EOL> try : <EOL> all_users_list = self . list_all_users ( ) <EOL> perm_items = self . get_all_permission_items ( ) <EOL> for user in all_users_list : <EOL> usr_cap = { '<STR_LIT:email>' : user } <EOL> caps_list = self . get_user_capabilities ( user ) <EOL> for perm in perm_items : <EOL> if perm in caps_list : <EOL> usr_cap [ perm ] = True <EOL> else : <EOL> usr_cap [ perm ] = False <EOL> ret_list . append ( usr_cap ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return ret_list <EOL> def get_all_permission_items ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ '<STR_LIT>' ] <EOL> def add_user_permissions ( self , email , perm ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> caps_list = self . get_user_capabilities ( email ) <EOL> uas = self . get_uaserver ( ) <EOL> new_caps = caps_list <EOL> if perm not in new_caps : <EOL> new_caps . append ( perm ) <EOL> else : <EOL> return True <EOL> ret = uas . set_capabilities ( email , <EOL> self . USER_CAPABILITIES_DELIMITER . join ( new_caps ) , GLOBAL_SECRET_KEY ) <EOL> if ret == '<STR_LIT:true>' : <EOL> self . cache [ '<STR_LIT>' ] [ email ] = new_caps <EOL> return True <EOL> else : <EOL> logging . error ( "<STR_LIT>" . format ( ret ) ) <EOL> return False <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return False <EOL> return True <EOL> def remove_user_permissions ( self , email , perm ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> caps_list = self . get_user_capabilities ( email ) <EOL> uas = self . get_uaserver ( ) <EOL> if perm in caps_list : <EOL> caps_list . remove ( perm ) <EOL> else : <EOL> return True <EOL> ret = uas . set_capabilities ( email , <EOL> self . USER_CAPABILITIES_DELIMITER . join ( caps_list ) , GLOBAL_SECRET_KEY ) <EOL> if ret == '<STR_LIT:true>' : <EOL> self . cache [ '<STR_LIT>' ] [ email ] = caps_list <EOL> return True <EOL> else : <EOL> logging . error ( "<STR_LIT>" . format ( ret ) ) <EOL> return False <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return False <EOL> return True <EOL> def gather_logs ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> acc = self . get_appcontroller_client ( ) <EOL> uuid = acc . gather_logs ( ) <EOL> return True , uuid <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return False , "<STR_LIT>" <EOL> def run_groomer ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> acc = self . get_appcontroller_client ( ) <EOL> return acc . run_groomer ( ) <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return str ( err ) <EOL> def change_password ( self , email , password ) : <EOL> """<STR_LIT>""" <EOL> hashed_password = hashlib . sha1 ( email + password ) . hexdigest ( ) <EOL> try : <EOL> user_app_server = self . get_uaserver ( ) <EOL> ret = user_app_server . change_password ( email , hashed_password , <EOL> GLOBAL_SECRET_KEY ) <EOL> if ret == "<STR_LIT:true>" : <EOL> return True , "<STR_LIT>" <EOL> else : <EOL> return False , ret <EOL> except Exception as err : <EOL> logging . exception ( err ) <EOL> return False , "<STR_LIT>" </s>
