def execute(self, provider=None, is_admin=False): system_provider = get_provider(self.provider_type) logger.info('run action %s, params: %s', self.provider_object, self.handle_extra_params()) self.annotate(execution_submitted=True) # admin use self provider, otherwise use system_provider if is_admin: if not provider: token, msg = system_provider.authenticate(self.submitter) logger.debug('get token: %s, msg: %s', token, msg) token = token['token'] provider = get_provider(self.provider_type, token=token, user=self.submitter) execution, msg = provider.run_action(self.provider_object, self.handle_extra_params()) annotate = provider.generate_annotation(execution) else: execution, msg = system_provider.run_action( self.provider_object, self.handle_extra_params()) annotate = system_provider.generate_annotation(execution) if not execution: self.annotate(execution_creation_success=False, execution_creation_msg=msg) return execution, msg self.executed_at = datetime.now() self.annotate(execution=annotate, execution_creation_success=True, execution_creation_msg=msg) # we don't save the ticket here, we leave it outside return execution, 'Success. <a href="%s" target="_blank">result</a>' % ( execution['web_url'], )
async def authenticate(request): '''Get user, password from request.form and authenticate with the provider to get a token, then set the token to session. ''' from helpdesk.config import ENABLED_PROVIDERS from helpdesk.models.provider import get_provider if request.method != 'POST': return form = await request.form() user = form.get('user') password = form.get('password') tokens, msgs = {}, [] for provider in ENABLED_PROVIDERS: system_provider = get_provider(provider) token, msg = system_provider.authenticate(user, password) msgs.append(f'{provider} msg: {msg}') logger.debug('get token: %s, msg: %s', token, msg) if token: request.session['user'] = user request.session[f'{provider}_token'] = token['token'] request.session[f'{provider}_expiry'] = token['expiry'] tokens[provider] = token['token'] return tokens, ' '.join(msgs)
async def authenticate(self, request): from helpdesk.models.user import User from helpdesk.models.provider import get_provider from helpdesk.config import ENABLED_PROVIDERS, AUTH_UNSUPPORT_PROVIDERS logger.debug('request.session: %s, user: %s', request.session, request.session.get('user')) for provider_type in ENABLED_PROVIDERS: if provider_type in AUTH_UNSUPPORT_PROVIDERS: continue if not all([ request.session.get('user'), request.session.get(f'{provider_type}_token'), request.session.get(f'{provider_type}_expiry') ]): logger.debug(f'{provider_type} auth error, unauth') return AuthCredentials([]), UnauthenticatedUser() # check token expiry, e.g. '2019-05-28T10:34:03.240708Z' expiry = request.session[f'{provider_type}_expiry'] if datetime.strptime(expiry, "%Y-%m-%dT%H:%M:%S.%fZ" ) < datetime.utcnow() + timedelta(minutes=1): logger.debug('token expiry time is in 1 minute, unauth.') unauth(request) return AuthCredentials([]), UnauthenticatedUser() username = request.session['user'] providers = { provider_type: get_provider(provider_type, token=request.session.get(f'{provider_type}_token'), user=username) for provider_type in ENABLED_PROVIDERS } user = User(username=username, providers=providers) return user.auth_credentials, user
def get_result(self, execution_output_id=None): provider = get_provider(self.provider_type) execution_id = self.annotation.get('execution', {}).get('id') if execution_output_id: execution, msg = provider.get_execution_output(execution_output_id) else: execution, msg = provider.get_execution(execution_id) return execution, msg
async def notify(self, phase): logger.info('Ticket notify: %s: %s', phase, self) assert isinstance(phase, TicketPhase) system_provider = get_provider(self.provider_type) for method in NOTIFICATION_METHODS: module, _class = method.split(':') try: notify = getattr(importlib.import_module(module), _class) await notify(system_provider, phase, self).send() except Exception as e: report() logger.warning('notify to %s failed: %s', method, e)
def get_result(self, provider=None, is_admin=False, execution_output_id=None): system_provider = get_provider(self.provider_type) # admin use self provider, otherwise use system_provider if is_admin: if not provider: token, msg = system_provider.authenticate(self.submitter) logger.debug('get token: %s, msg: %s', token, msg) token = token['token'] provider = get_provider(self.provider_type, token=token, user=self.submitter) else: provider = system_provider execution_id = self.annotation.get('execution', {}).get('id') if execution_output_id: execution, msg = provider.get_execution_output(execution_output_id) else: execution, msg = provider.get_execution(execution_id) return execution, msg
def resolve_pack(self, *config): name = config[0] provider_object = config[-1] provider_type = config[-2] pack = provider_object[:-1] sub_actions = [] system_provider = get_provider(provider_type) actions = system_provider.get_actions(pack=pack) for a in actions: obj = '.'.join([a.get('pack'), a.get('name')]) desc = a.get('description') sub_actions.append([obj, desc, provider_type, a['id']]) return [name, sub_actions]
async def action(request): target_object = request.path_params.get('target_object', '').strip('/') # check if action exists action = action_tree.get_action_by_target_obj(target_object) if not action: raise ApiError(ApiErrors.not_found) provider = get_provider(action.provider_type) if request.method == 'GET': return action.to_dict(provider, request.user) if request.method == 'POST': form = await request.form() ticket, msg = await action.run(provider, form, request.user) msg_level = 'success' if bool(ticket) else 'error' return dict(ticket=ticket, msg=msg, msg_level=msg_level, debug=config.DEBUG)
def execute(self): provider = get_provider(self.provider_type) logger.info('run action %s, params: %s', self.provider_object, self.handle_extra_params()) self.annotate(execution_submitted=True) execution, msg = provider.run_action(self.provider_object, self.handle_extra_params()) annotate = provider.generate_annotation(execution) if not execution: self.annotate(execution_creation_success=False, execution_creation_msg=msg) return execution, msg self.executed_at = datetime.now() self.annotate(execution=annotate, execution_creation_success=True, execution_creation_msg=msg) # we don't save the ticket here, we leave it outside return execution, 'Success. <a href="%s" target="_blank">result</a>' % ( execution['web_url'], )
def resolve_pack(self, *config): name = config[0] provider_object = config[-1] provider_type = config[-2] pack = provider_object[:-1] sub_actions = [] actions = [] try: system_provider = get_provider(provider_type) actions = system_provider.get_actions(pack=pack) except (InitProviderError, ResolvePackageError) as e: logger.error(f"Resolve pack {name} error:\n{e.tb}") # insert a empty children to failed action tree # so we can tolerant provider partially failed # and frontend can check children empty to notify user report() for a in actions: obj = '.'.join([a.get('pack'), a.get('name')]) desc = a.get('description') sub_actions.append([obj, desc, provider_type, a['id']]) return [name, sub_actions]