def __init__(self): self.use_compact_serializer = True # self.current = None self.wf_activities = {} self.workflow = BpmnWorkflow self.workflow_spec_cache = {} self.workflow_spec = WorkflowSpec() self.user_model = get_object_from_path(settings.USER_MODEL) self.role_model = get_object_from_path(settings.ROLE_MODEL)
def run(self): """ Creates new permissions. """ from pyoko.lib.utils import get_object_from_path from zengine.config import settings model = get_object_from_path(settings.PERMISSION_MODEL) perm_provider = get_object_from_path(settings.PERMISSION_PROVIDER) existing_perms = [] new_perms = [] for code, name, desc in perm_provider(): code = six.text_type(code) if self.manager.args.dry: exists = model.objects.filter(code=code, name=name) if exists: perm = exists[0] new = False else: new = True perm = model(code=code, name=name) else: try: perm = model.objects.get(code) existing_perms.append(perm) except ObjectDoesNotExist: perm = model(description=desc, code=code, name=name) perm.key = code perm.save() new_perms.append(perm) # perm, new = model.objects.get_or_create({'description': desc}, code=code, name=name) # if new: # new_perms.append(perm) # else: # existing_perms.append(perm) report = "\n\n%s permission(s) were found in DB. " % len( existing_perms) if new_perms: report += "\n%s new permission record added. " % len(new_perms) else: report += 'No new perms added. ' if new_perms: if not self.manager.args.dry: SelectBoxCache.flush(model.__name__) report += 'Total %s perms exists.' % (len(existing_perms) + len(new_perms)) report = "\n + " + "\n + ".join( [p.name or p.code for p in new_perms]) + report if self.manager.args.dry: print("\n~~~~~~~~~~~~~~ DRY RUN ~~~~~~~~~~~~~~\n") print(report + "\n")
def __init__(self, **kwargs): self.task_data = {'cmd': None} self.session = Session() self.headers = {} self.input = {} # when we want to use engine functions independently, self.output = {} # we need to create a fake current object try: self.session = kwargs['session'] self.input = kwargs['input'] except KeyError: self.request = kwargs.pop('request', {}) self.response = kwargs.pop('response', {}) if 'env' in self.request: self.session = self.request.env['session'] self.input = self.request.context['data'] self.output = self.request.context['result'] self.remote_addr = None self.user_id = self.session.get('user_id') self.role_id = self.session.get('role_id') self.log = log self.pool = {} AuthBackend = get_object_from_path(settings.AUTH_BACKEND) self.auth = lazy_object_proxy.Proxy(lambda: AuthBackend(self)) self.user = lazy_object_proxy.Proxy(lambda: self.auth.get_user()) self.role = lazy_object_proxy.Proxy(lambda: self.auth.get_role()) log.debug("\n\nINPUT DATA: %s" % self.input) self.permissions = []
def __init__(self, **kwargs): self.task_data = {'cmd': None} self.request = kwargs.pop('request', {}) self.response = kwargs.pop('response', {}) try: self.session = self.request.env['session'] self.input = self.request.context['data'] self.output = self.request.context['result'] self.user_id = self.session.get('user_id') self.role_id = self.session.get('role_id') except AttributeError: # when we want to use engine functions independently, # we need to create a fake current object self.session = {} self.input = {} self.output = {} self.user_id = None self.role_id = None self.lang_code = self.input.get('lang_code', settings.DEFAULT_LANG) self.log = log self.pool = {} AuthBackend = get_object_from_path(settings.AUTH_BACKEND) self.auth = lazy_object_proxy.Proxy(lambda: AuthBackend(self)) self.user = lazy_object_proxy.Proxy(lambda: self.auth.get_user()) self.role = lazy_object_proxy.Proxy(lambda: self.auth.get_role()) self.msg_cache = Notify(self.user_id) log.debug("\n\nINPUT DATA: %s" % self.input) self.permissions = []
def view_connector(view_path): """ A connector for non-workflow views """ view = get_object_from_path(view_path) class Caller(object): @staticmethod def on_get(req, resp, *args, **kwargs): Caller.on_post(req, resp, *args, **kwargs) @staticmethod def on_post(req, resp, *args, **kwargs): try: current = Current(request=req, response=resp) if not (current.is_auth or view_path in settings.ANONYMOUS_WORKFLOWS): raise falcon.HTTPUnauthorized("Login required", view_path) view(current, *args, **kwargs) except HTTPError: raise except: if settings.DEBUG: resp.status = falcon.HTTP_500 resp.body = json.dumps({"error": traceback.format_exc()}) else: raise return Caller
def view_connector(view_path): """ A connector for non-workflow views """ view = get_object_from_path(view_path) class Caller(object): @staticmethod def on_get(req, resp, *args, **kwargs): Caller.on_post(req, resp, *args, **kwargs) @staticmethod def on_post(req, resp, *args, **kwargs): try: current = Current(request=req, response=resp) if not (current.is_auth or view_path in settings.ANONYMOUS_WORKFLOWS): raise falcon.HTTPUnauthorized("Login required", view_path) view(current, *args, **kwargs) except HTTPError: raise except: if settings.DEBUG: resp.status = falcon.HTTP_500 resp.body = json.dumps({'error': traceback.format_exc()}) else: raise return Caller
def run(self): from pyoko.lib.utils import get_object_from_path from zengine.config import settings model = get_object_from_path(settings.PERMISSION_MODEL) perm_provider = get_object_from_path(settings.PERMISSION_PROVIDER) existing_perms = [] new_perms = [] for code, name, desc in perm_provider(): if self.manager.args.dry: exists = model.objects.filter(code=code, name=name) if exists: perm = exists[0] new = False else: new = True perm = model(code=code, name=name) else: perm, new = model.objects.get_or_create({'description': desc}, code=code, name=name) if new: new_perms.append(perm) else: existing_perms.append(perm) report = "\n\n%s permission(s) were found in DB. " % len( existing_perms) if new_perms: report += "\n%s new permission record added. " % len(new_perms) else: report += 'No new perms added. ' if new_perms: if not self.manager.args.dry: ModelListCache.flush(model.__name__) report += 'Total %s perms exists.' % (len(existing_perms) + len(new_perms)) report = "\n + " + "\n + ".join([p.name for p in new_perms]) + report if self.manager.args.dry: print("\n~~~~~~~~~~~~~~ DRY RUN ~~~~~~~~~~~~~~\n") print(report + "\n")
def start_engine(self, **kwargs): """ Initializes the workflow with given request, response objects and diagram name. Args: session: input: workflow_name (str): Name of workflow diagram without ".bpmn" suffix. File must be placed under one of configured :py:attr:`~zengine.settings.WORKFLOW_PACKAGES_PATHS` """ self.current = WFCurrent(**kwargs) self.wf_state = {'in_external': False, 'finished': False} if not self.current.new_token: self.wf_state = self.current.wf_cache.get(self.wf_state) self.current.workflow_name = self.wf_state['name'] # if we have a pre-selected object to work with, # inserting it as current.input['id'] and task_data['object_id'] if 'subject' in self.wf_state: self.current.input['id'] = self.wf_state['subject'] self.current.task_data['object_id'] = self.wf_state['subject'] self.check_for_authentication() self.check_for_permission() self.workflow = self.load_or_create_workflow() # if form data exists in input (user submitted) # put form data in wf task_data if 'form' in self.current.input: form = self.current.input['form'] if 'form_name' in form: self.current.task_data[form['form_name']] = form # in wf diagram, if property is stated as init = True # demanded initial values are assigned and put to cache start_init_values = self.workflow_spec.wf_properties.get( 'init', 'False') == 'True' if start_init_values: WFInit = get_object_from_path(settings.WF_INITIAL_VALUES)() WFInit.assign_wf_initial_values(self.current) log_msg = ( "\n\n::::::::::: ENGINE STARTED :::::::::::\n" "\tWF: %s (Possible) TASK:%s\n" "\tCMD:%s\n" "\tSUBCMD:%s" % (self.workflow.name, self.workflow.get_tasks(Task.READY), self.current.input.get('cmd'), self.current.input.get('subcmd'))) log.debug(log_msg) sys._zops_wf_state_log = log_msg self.current.workflow = self.workflow
def create_user_channels(self): from zengine.messaging.model import Channel, Subscriber user_model = get_object_from_path(settings.USER_MODEL) with BlockSave(Channel): for usr in user_model.objects.all(): # create private exchange of user # create notification subscription to private exchange ch, new_ch, sb, new_sb = usr.prepare_channels() print("%s exchange: %s" % ('created' if new_ch else 'existing', ch.code_name)) print("%s notify sub: %s" % ('created' if new_sb else 'existing', ch.code_name))
def run(self): from pyoko.lib.utils import get_object_from_path from zengine.config import settings model = get_object_from_path(settings.PERMISSION_MODEL) perm_provider = get_object_from_path(settings.PERMISSION_PROVIDER) existing_perms = [] new_perms = [] for code, name, desc in perm_provider(): if self.manager.args.dry: exists = model.objects.filter(code=code, name=name) if exists: perm = exists[0] new = False else: new = True perm = model(code=code, name=name) else: perm, new = model.objects.get_or_create({'description': desc}, code=code, name=name) if new: new_perms.append(perm) else: existing_perms.append(perm) report = "\n\n%s permission(s) were found in DB. " % len(existing_perms) if new_perms: report += "\n%s new permission record added. " % len(new_perms) else: report += 'No new perms added. ' if new_perms: if not self.manager.args.dry: ModelListCache.flush(model.__name__) report += 'Total %s perms exists.' % (len(existing_perms) + len(new_perms)) report = "\n + " + "\n + ".join([p.name for p in new_perms]) + report if self.manager.args.dry: print("\n~~~~~~~~~~~~~~ DRY RUN ~~~~~~~~~~~~~~\n") print(report + "\n")
def run_activity(self): """ imports, caches and calls the associated activity of the current task """ if self.current.activity: if self.current.activity not in self.workflow_methods: for activity_package in settings.ACTIVITY_MODULES_IMPORT_PATHS: try: full_path = "%s.%s" % (activity_package, self.current.activity) self.workflow_methods[self.current.activity] = get_object_from_path(full_path) break except: number_of_paths = len(settings.ACTIVITY_MODULES_IMPORT_PATHS) index_no = settings.ACTIVITY_MODULES_IMPORT_PATHS.index(activity_package) if index_no + 1 == number_of_paths: # raise if cant find the activity in the last path raise self.workflow_methods[self.current.activity](self.current)
def send_message_for_lane_change(sender, *args, **kwargs): from zengine.lib.catalog_data import gettxt as _ from pyoko.lib.utils import get_object_from_path UserModel = get_object_from_path(settings.USER_MODEL) from zengine.notifications import Notify current = kwargs['current'] old_lane = kwargs['old_lane'] owners = kwargs['possible_owners'] if 'lane_change_invite' in current.task_data: msg_context = current.task_data.pop('lane_change_invite') else: msg_context = DEFAULT_LANE_CHANGE_INVITE_MSG for recipient in owners: if not isinstance(recipient, UserModel): recipient = recipient.get_user() Notify(recipient.key).set_message(title=_(msg_context['title']), body=_(msg_context['body']), type=Notify.TaskInfo, url=current.get_wf_url() )
def run(self): from pyoko.lib.utils import get_object_from_path from zengine.auth.permissions import get_all_permissions from zengine.config import settings model = get_object_from_path(settings.PERMISSION_MODEL) perms = [] new_perms = [] for code, name, desc in get_all_permissions(): perm, new = model.objects.get_or_create({'description': desc}, code=code, name=name) perms.append(perm) if new: new_perms.append(perm) if len(perms) == len(new_perms): report = '' else: report = "\nTotal %s permission exist. " % len(perms) report += "\n%s new permission record added.\n\n" % len(new_perms) if new_perms: report = "\n + " + "\n + ".join([p.name for p in new_perms]) + report return report
# -*- coding: utf-8 -*- """ """ # Copyright (C) 2016 ZetaOps Inc. # # This file is licensed under the GNU General Public License v3 # (GPLv3). See LICENSE.txt for details. from zengine.lib.test_utils import BaseTestCase from zengine.models import TaskInvitation from pyoko.lib.utils import get_object_from_path from pyoko.conf import settings RoleModel = get_object_from_path(settings.ROLE_MODEL) class TestCase(BaseTestCase): def test_assign_yourself(self): # Test data is reset inv = TaskInvitation.objects.get("Ewn4V1Iih7htogD7kLyyWthswxr") inv.role = RoleModel() wfi = inv.instance wfi.current_actor = RoleModel() wfi.save() inv.save() # We will take the workflow to ourselves. for i in range(2): self.prepare_client('/task_assign_yourself/', username='******') resp = self.client.post(filters={
can simply read json data from current.input and write back to current.output """ # Copyright (C) 2015 ZetaOps Inc. # # This file is licensed under the GNU General Public License v3 # (GPLv3). See LICENSE.txt for details. import falcon from beaker.middleware import SessionMiddleware from pyoko.lib.utils import get_object_from_path from zengine.config import settings from zengine.engine import ZEngine falcon_app = falcon.API(middleware=[get_object_from_path(mw_class)() for mw_class in settings.ENABLED_MIDDLEWARES]) app = SessionMiddleware(falcon_app, settings.SESSION_OPTIONS, environ_key="session") class Connector(object): """ this is object will be used to catch all requests from falcon and map them to workflow engine. a request to domain.com/show_dashboard/ will invoke a workflow named show_dashboard with the payload json data """ def __init__(self): self.engine = ZEngine() def on_get(self, req, resp, wf_name):
import traceback from falcon.http_error import HTTPError import falcon from beaker.middleware import SessionMiddleware from pyoko.lib.utils import get_object_from_path from zengine.config import settings from zengine.engine import ZEngine, Current # receivers should be imported at right time, right place # they will not registered if not placed in a central location # but they can cause "cannot import settings" errors if imported too early from zengine.receivers import * falcon_app = falcon.API(middleware=[ get_object_from_path(mw_class)() for mw_class in settings.ENABLED_MIDDLEWARES ]) app = SessionMiddleware(falcon_app, settings.SESSION_OPTIONS, environ_key="session") # class crud_handler(object): # """ # this object redirects /ModelName/ type queries to /crud with ModelName as part of JSON payload # """ # @staticmethod # def on_get(req, resp, model_name): # req.context['data']['model'] = model_name # wf_connector(req, resp, 'crud') #
# -*- coding: utf-8 -*- """configuration""" # Copyright (C) 2015 ZetaOps Inc. # # This file is licensed under the GNU General Public License v3 # (GPLv3). See LICENSE.txt for details. import importlib from beaker.cache import _backends import os import beaker from beaker_extensions import redis_ from pyoko.lib.utils import get_object_from_path settings = importlib.import_module(os.getenv('ZENGINE_SETTINGS')) AuthBackend = get_object_from_path(settings.AUTH_BACKEND) beaker.cache.clsmap = _backends({'redis': redis_.RedisManager})
def file_manager(self): return get_object_from_path(settings.FILE_MANAGER)
import json import traceback from falcon.http_error import HTTPError import falcon from beaker.middleware import SessionMiddleware from pyoko.lib.utils import get_object_from_path from zengine.config import settings from zengine.engine import ZEngine, Current # receivers should be imported at right time, right place # they will not registered if not placed in a central location # but they can cause "cannot import settings" errors if imported too early from zengine.receivers import * falcon_app = falcon.API(middleware=[get_object_from_path(mw_class)() for mw_class in settings.ENABLED_MIDDLEWARES]) app = SessionMiddleware(falcon_app, settings.SESSION_OPTIONS, environ_key="session") # class crud_handler(object): # """ # this object redirects /ModelName/ type queries to /crud with ModelName as part of JSON payload # """ # @staticmethod # def on_get(req, resp, model_name): # req.context['data']['model'] = model_name # wf_connector(req, resp, 'crud') # # @staticmethod # def on_post(req, resp, model_name): # req.context['data']['model'] = model_name
# -*- coding: utf-8 -*- # Copyright (C) 2015 ZetaOps Inc. # # This file is licensed under the GNU General Public License v3 # (GPLv3). See LICENSE.txt for details. from zengine.views.crud import CrudView from zengine.forms import JsonForm from zengine.forms import fields from zengine.lib.utils import gettext as _ from zengine import settings from pyoko.lib.utils import get_object_from_path AuthBackend = get_object_from_path(settings.AUTH_BACKEND) class RoleSwitching(CrudView): """ Switches current user's role. """ def list_user_roles(self): """ Lists user roles as selectable except user's current role. """ _form = JsonForm(current=self.current, title=_(u"Switch Role")) _form.help_text = "Your current role: %s %s" % ( self.current.role.unit.name, self.current.role.abstract_role.name) switch_roles = self.get_user_switchable_roles() _form.role_options = fields.Integer( _(u"Please, choose the role you want to switch:"), choices=switch_roles,
from zengine.views.base import BaseView from zengine import forms from zengine.forms import fields from zengine.lib.cache import Cache from zengine.config import settings from pyoko import ListNode from pyoko.lib.utils import get_object_from_path from collections import defaultdict PermissionModel = get_object_from_path(settings.PERMISSION_MODEL) RoleModel = get_object_from_path(settings.ROLE_MODEL) class PermissionForm(forms.JsonForm): """Form used to edit the permissions of a role.""" class Meta: title = 'Edit Permissions' exclude = ['Permissions'] class Permissions(ListNode): perm_name = fields.String('Permission Name') save_edit = fields.Button("Save", cmd="finish") class PermissionTreeBuilder(object): """A class to help permission trees to be built out of permission objects. The permission trees built by this class will be in the form of {
from pika.exceptions import ConnectionClosed from pyoko import Model, field, ListNode from pyoko.conf import settings from pyoko.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from pyoko.fields import DATE_TIME_FORMAT from pyoko.lib.utils import get_object_from_path from SpiffWorkflow.bpmn.parser.util import BPMN_MODEL_NS, ATTRIBUTE_NS from pyoko.modelmeta import model_registry from zengine.client_queue import get_mq_connection from zengine.lib.cache import Cache from zengine.lib.translation import gettext_lazy as __ import xml.etree.ElementTree as ET from zengine.lib.decorators import ROLE_GETTER_CHOICES, bg_job, ROLE_GETTER_METHODS UnitModel = get_object_from_path(settings.UNIT_MODEL) RoleModel = get_object_from_path(settings.ROLE_MODEL) AbstractRoleModel = get_object_from_path(settings.ABSTRACT_ROLE_MODEL) class DiagramXML(Model): """ Diagram XML versions """ body = field.String(__(u"XML content"), index=False) name = field.String(__(u"Name")) @classmethod def get_or_create_by_content(cls, name, content): """ if xml content updated, create a new entry for given wf name
# Copyright (C) 2015 ZetaOps Inc. # # This file is licensed under the GNU General Public License v3 # (GPLv3). See LICENSE.txt for details. from pyoko.conf import settings from pyoko.db.adapter.db_riak import BlockSave from pyoko.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from pyoko.lib.utils import get_object_from_path from zengine.lib.decorators import view from zengine.log import log from zengine.lib.exceptions import HTTPError from zengine.messaging.model import Channel, Attachment, Subscriber, Message, Favorite, \ FlaggedMessage UserModel = get_object_from_path(settings.USER_MODEL) UnitModel = get_object_from_path(settings.UNIT_MODEL) """ .. code-block:: python MSG_DICT = { 'content': string, 'title': string, 'timestamp': datetime, 'updated_at': datetime, 'is_update': boolean, # false for new messages # true if this is an updated message 'channel_key': key, 'sender_name': string,