Example #1
0
    def destroy(self, request, pk):
        entry: Entry = self.get_object()
        if not entry.is_active:
            raise ValidationError("specified entry has already been deleted")

        user: User = request.user

        if custom_view.is_custom("before_delete_entry_v2", entry.schema.name):
            custom_view.call_custom("before_delete_entry_v2",
                                    entry.schema.name, user, entry)

        # register operation History for deleting entry
        user.seth_entry_del(entry)

        # delete entry
        entry.delete(deleted_user=user)

        if custom_view.is_custom("after_delete_entry_v2", entry.schema.name):
            custom_view.call_custom("after_delete_entry_v2", entry.schema.name,
                                    user, entry)

        # Send notification to the webhook URL
        job_notify: Job = Job.new_notify_delete_entry(user, entry)
        job_notify.run()

        return Response(status=status.HTTP_204_NO_CONTENT)
Example #2
0
def create(request, entity_id):
    user = User.objects.get(id=request.user.id)
    entity, error = get_object_with_check_permission(user, Entity, entity_id, ACLType.Writable)
    if error:
        return error

    if custom_view.is_custom("create_entry_without_context", entity.name):
        # show custom view
        return custom_view.call_custom("create_entry_without_context", entity.name, request, user,
                                       entity)

    context = {
        'entity': entity,
        'form_url': '/entry/do_create/%s/' % entity.id,
        'redirect_url': '/entry/%s' % entity.id,
        'groups': Group.objects.filter(is_active=True),
        'attributes': [{
            'entity_attr_id': x.id,
            'id': x.id,
            'type': x.type,
            'name': x.name,
            'is_mandatory': x.is_mandatory,
            'is_readble': True if user.has_permission(x, ACLType.Writable) else False
        } for x in entity.attrs.filter(is_active=True).order_by('index')]
    }

    if custom_view.is_custom("create_entry", entity.name):
        # show custom view
        return custom_view.call_custom("create_entry", entity.name, request, user, entity, context)
    else:
        return render(request, 'create_entry.html', context)
Example #3
0
def index(request, entity_id):
    if not Entity.objects.filter(id=entity_id).exists():
        return HttpResponse('Failed to get entity of specified id', status=400)

    entity = Entity.objects.get(id=entity_id)
    if custom_view.is_custom("list_entry_without_context", entity.name):
        # show custom view without context
        resp = custom_view.call_custom("list_entry_without_context", entity.name, request, entity)
        if resp:
            return resp

    entries = Entry.objects.order_by('name').filter(schema=entity, is_active=True)

    total_count = list_count = len(entries)
    if(len(entries) > CONFIG.MAX_LIST_ENTRIES):
        entries = entries[0:CONFIG.MAX_LIST_ENTRIES]
        list_count = CONFIG.MAX_LIST_ENTRIES

    context = {
        'entity': entity,
        'entries': entries,
        'total_count': total_count,
        'list_count': list_count,
    }

    if custom_view.is_custom("list_entry", entity.name):
        # list custom view
        return custom_view.call_custom("list_entry", entity.name, request, entity, context)
    else:
        # list ordinal view
        return render(request, 'list_entry.html', context)
Example #4
0
def create(request, entity_id):
    user = User.objects.get(id=request.user.id)

    if not Entity.objects.filter(id=entity_id).exists():
        return HttpResponse('Failed to get entity of specified id', status=400)

    entity = Entity.objects.get(id=entity_id)
    if custom_view.is_custom("create_entry_without_context", entity.name):
        # show custom view
        return custom_view.call_custom("create_entry_without_context", entity.name, request, user,
                                       entity)

    context = {
        'entity': entity,
        'form_url': '/entry/do_create/%s/' % entity.id,
        'redirect_url': '/entry/%s' % entity.id,
        'groups': Group.objects.filter(is_active=True),
        'attributes': [{
            'id': x.id,
            'type': x.type,
            'name': x.name,
            'is_mandatory': x.is_mandatory,
        } for x in entity.attrs.filter(is_active=True).order_by('index')
            if user.has_permission(x, ACLType.Writable)]
    }

    if custom_view.is_custom("create_entry", entity.name):
        # show custom view
        return custom_view.call_custom("create_entry", entity.name, request, user, entity, context)
    else:
        return render(request, 'create_entry.html', context)
Example #5
0
    def destroy(self, request, pk):
        entity: Entity = self.get_object()
        user: User = request.user

        if not entity.is_active:
            raise ValidationError("specified entity has already been deleted")

        if Entry.objects.filter(schema=entity, is_active=True).exists():
            raise ValidationError(
                "cannot delete Entity because one or more Entries are not deleted"
            )

        if custom_view.is_custom("before_delete_entity_v2"):
            custom_view.call_custom("before_delete_entity_v2", None, user,
                                    entity)

        # register operation History for deleting entity
        history: History = user.seth_entity_del(entity)

        entity.delete()

        # Delete all attributes which target Entity have
        entity_attr: EntityAttr
        for entity_attr in entity.attrs.filter(is_active=True):
            history.del_attr(entity_attr)
            entity_attr.delete()

        if custom_view.is_custom("after_delete_entity_v2"):
            custom_view.call_custom("after_delete_entity_v2", None, user,
                                    entity)

        return Response(status=status.HTTP_204_NO_CONTENT)
Example #6
0
def index(request, entity_id):
    entity, error = get_obj_with_check_perm(request.user, Entity, entity_id,
                                            ACLType.Readable)
    if error:
        return error

    page = request.GET.get("page", 1)
    keyword = request.GET.get("keyword", None)

    if custom_view.is_custom("list_entry_without_context", entity.name):
        # show custom view without context
        resp = custom_view.call_custom("list_entry_without_context",
                                       entity.name, request, entity)
        if resp:
            return resp

    if keyword:
        name_pattern = prepend_escape_character(
            CONFIG.ESCAPE_CHARACTERS_ENTRY_LIST, keyword)
        entries = Entry.objects.order_by("name").filter(
            schema=entity, is_active=True, name__iregex=name_pattern)
    else:
        entries = Entry.objects.order_by("name").filter(schema=entity,
                                                        is_active=True)

    p = Paginator(entries, CONFIG.MAX_LIST_ENTRIES)
    try:
        page_obj = p.page(page)
    except PageNotAnInteger:
        return HttpResponse("Invalid page number. It must be unsigned integer",
                            status=400)
    except EmptyPage:
        return HttpResponse(
            "Invalid page number. The page doesn't have anything", status=400)

    context = {
        "entity": entity,
        "keyword": keyword,
        "page_obj": page_obj,
    }

    if custom_view.is_custom("list_entry", entity.name):
        # list custom view
        return custom_view.call_custom("list_entry", entity.name, request,
                                       entity, context)
    else:
        # list ordinal view
        return render(request, "list_entry.html", context)
Example #7
0
def copy_entry(self, user_id, src_entry_id, job_id):
    job = Job.objects.get(id=job_id)

    # wait dependent job is finished
    job.wait_dependent_job()

    if job.is_ready_to_process():
        # update job status
        job.set_status(Job.STATUS['PROCESSING'])

        user = User.objects.get(id=user_id)
        src_entry = Entry.objects.get(id=src_entry_id)

        params = json.loads(job.params)
        dest_entry = Entry.objects.filter(schema=src_entry.schema,
                                          name=params['new_name']).first()
        if not dest_entry:
            dest_entry = src_entry.clone(user, name=params['new_name'])
            dest_entry.register_es()

        if custom_view.is_custom("after_copy_entry", src_entry.schema.name):
            custom_view.call_custom("after_copy_entry", src_entry.schema.name,
                                    user, src_entry, dest_entry,
                                    params['post_data'])

        # update job status and save it
        job.target = dest_entry
        job.status = Job.STATUS['DONE']
        job.text = 'original entry: %s' % src_entry.name

        job.save()
Example #8
0
def restore_entry(self, entry_id, job_id):
    job = Job.objects.get(id=job_id)

    # wait dependent job is finished
    job.wait_dependent_job()

    if job.is_ready_to_process():
        job.set_status(Job.STATUS['PROCESSING'])

        entry = Entry.objects.get(id=entry_id)
        entry.restore()

        # remove status flag which is set before calling this
        entry.del_status(Entry.STATUS_CREATING)

        # calling custom view processing if necessary
        if custom_view.is_custom("after_restore_entry", entry.schema.name):
            custom_view.call_custom("after_restore_entry", entry.schema.name,
                                    job.user, entry)

        # update entry information to Elasticsearch
        entry.register_es()

        # update job status and save it
        job.status = Job.STATUS['DONE']
        job.save()
Example #9
0
def do_create(request, entity_id, recv_data):
    # get objects to be referred in the following processing
    user = User.objects.get(id=request.user.id)
    entity = Entity.objects.get(id=entity_id)

    # checks that a same name entry corresponding to the entity is existed, or not.
    if Entry.objects.filter(schema=entity_id, name=recv_data['entry_name']).exists():
        return HttpResponse('Duplicate name entry is existed', status=400)

    # validate contexts of each attributes
    err = _validate_input(recv_data, entity)
    if err:
        return err

    if custom_view.is_custom("do_create_entry", entity.name):
        # resp is HttpReponse instance or its subclass (e.g. JsonResponse)
        resp = custom_view.call_custom(
            "do_create_entry", entity.name, request, recv_data, user, entity)
        if resp:
            return resp

    # Create a new Entry object
    entry = Entry.objects.create(name=recv_data['entry_name'],
                                 created_user=user,
                                 schema=entity,
                                 status=Entry.STATUS_CREATING)

    # Create a new job to create entry and run it
    job = Job.new_create(user, entry, params=recv_data)
    job.run()

    return JsonResponse({
        'entry_id': entry.id,
        'entry_name': entry.name,
    })
Example #10
0
def do_copy_entry(self, job_id):
    job = Job.objects.get(id=job_id)

    if job.proceed_if_ready():
        # update job status
        job.update(Job.STATUS["PROCESSING"])

        user = User.objects.get(id=job.user.id)
        src_entry = Entry.objects.get(id=job.target.id)

        params = json.loads(job.params)
        dest_entry = Entry.objects.filter(schema=src_entry.schema,
                                          name=params["new_name"]).first()
        if not dest_entry:
            dest_entry = src_entry.clone(user, name=params["new_name"])
            dest_entry.register_es()

        if custom_view.is_custom("after_copy_entry", src_entry.schema.name):
            custom_view.call_custom(
                "after_copy_entry",
                src_entry.schema.name,
                user,
                src_entry,
                dest_entry,
                params["post_data"],
            )

        # update job status and save it
        job.update(Job.STATUS["DONE"], "original entry: %s" % src_entry.name,
                   dest_entry)

        # create and run event notification job
        job_notify_event = Job.new_notify_create_entry(user, dest_entry)
        job_notify_event.run()
Example #11
0
def copy_entry(self, job_id):
    job = Job.objects.get(id=job_id)

    if job.proceed_if_ready():
        # update job status
        job.update(Job.STATUS['PROCESSING'])

        user = User.objects.get(id=job.user.id)
        src_entry = Entry.objects.get(id=job.target.id)

        params = json.loads(job.params)
        dest_entry = Entry.objects.filter(schema=src_entry.schema,
                                          name=params['new_name']).first()
        if not dest_entry:
            dest_entry = src_entry.clone(user, name=params['new_name'])
            dest_entry.register_es()

        if custom_view.is_custom("after_copy_entry", src_entry.schema.name):
            custom_view.call_custom("after_copy_entry", src_entry.schema.name,
                                    user, src_entry, dest_entry,
                                    params['post_data'])

        # update job status and save it
        job.update(Job.STATUS['DONE'], 'original entry: %s' % src_entry.name,
                   dest_entry)
Example #12
0
def copy(request, entry_id):
    entry, error = get_obj_with_check_perm(request.user, Entry, entry_id,
                                           ACLType.Writable)
    if error:
        return error

    # prevent to show edit page under the creating processing
    if entry.get_status(Entry.STATUS_CREATING) or entry.get_status(
            Entry.STATUS_EDITING):
        return HttpResponse("Target entry is now under processing", status=400)

    if not entry.is_active:
        return _redirect_restore_entry(entry)

    context = {
        "form_url": "/entry/do_copy/%s" % entry.id,
        "redirect_url": "/entry/%s" % entry.schema.id,
        "entry": entry,
    }

    if custom_view.is_custom("copy_entry", entry.schema.name):
        return custom_view.call_custom("copy_entry", entry.schema.name,
                                       request, request.user, entry, context)

    return render(request, "copy_entry.html", context)
Example #13
0
def copy(request, entry_id):
    user = User.objects.get(id=request.user.id)

    if not Entry.objects.filter(id=entry_id).exists():
        return HttpResponse('Failed to get an Entry object of specified id', status=400)

    entry = Entry.objects.get(id=entry_id)

    # prevent to show edit page under the creating processing
    if entry.get_status(Entry.STATUS_CREATING) or entry.get_status(Entry.STATUS_EDITING):
        return HttpResponse('Target entry is now under processing', status=400)

    if not entry.is_active:
        return HttpResponse('Target entry has been deleted', status=400)

    context = {
        'form_url': '/entry/do_copy/%s' % entry.id,
        'redirect_url': '/entry/%s' % entry.schema.id,
        'entry': entry,
    }

    if custom_view.is_custom("copy_entry", entry.schema.name):
        return custom_view.call_custom("copy_entry", entry.schema.name, request, user, entry,
                                       context)

    return render(request, 'copy_entry.html', context)
Example #14
0
def edit(request, entry_id):
    user = User.objects.get(id=request.user.id)

    if not Entry.objects.filter(id=entry_id).exists():
        return HttpResponse('Failed to get an Entry object of specified id', status=400)

    entry = Entry.objects.get(id=entry_id)

    # prevent to show edit page under the creating processing
    if entry.get_status(Entry.STATUS_CREATING):
        return HttpResponse('Target entry is now under processing', status=400)

    if not entry.is_active:
        return HttpResponse('Target entry has been deleted', status=400)

    entry.complement_attrs(user)

    context = {
        'entry': entry,
        'groups': Group.objects.filter(is_active=True),
        'attributes': entry.get_available_attrs(user, ACLType.Writable, get_referral_entries=True),
        'form_url': '/entry/do_edit/%s' % entry.id,
        'redirect_url': '/entry/show/%s' % entry.id,
    }

    if custom_view.is_custom("edit_entry", entry.schema.name):
        # show custom view
        return custom_view.call_custom("edit_entry", entry.schema.name, request, user, entry,
                                       context)
    else:
        return render(request, 'edit_entry.html', context)
Example #15
0
def show(request, entry_id):
    user = User.objects.get(id=request.user.id)

    try:
        entry = Entry.objects.extra(
            where=['status & %d = 0' % Entry.STATUS_CREATING]).get(id=entry_id)
    except ObjectDoesNotExist:
        return HttpResponse('Failed to get an Entry object of specified id', status=400)

    if entry.get_status(Entry.STATUS_CREATING):
        return HttpResponse('Target entry is now under processing', status=400)

    if not entry.is_active:
        return HttpResponse('Target entry has been deleted', status=400)

    # create new attributes which are appended after creation of Entity
    entry.complement_attrs(user)

    context = {
        'entry': entry,
        'attributes': entry.get_available_attrs(user),
    }

    if custom_view.is_custom("show_entry", entry.schema.name):
        # show custom view
        return custom_view.call_custom("show_entry", entry.schema.name, request, user, entry,
                                       context)
    else:
        # show ordinal view
        return render(request, 'show_entry.html', context)
Example #16
0
    def import_obj(self, instance, data, dry_run):
        if not Entity.objects.filter(name=data["entity"]).exists():
            raise RuntimeError("failed to identify entity object")

        if data["refer"] and not all([
                Entity.objects.filter(name=x).exists()
                for x in data["refer"].split(",")
        ]):
            raise RuntimeError("refer to invalid entity object")

        # The processing fails when 'type' parameter is not existed for creating a new instance
        if not instance.pk and not data["type"]:
            raise RuntimeError(
                "The parameter 'type' is mandatory when a new EntityAtter create"
            )

        # Set event handler for custom-view. When it returns not None, then it abort to import.
        if custom_view.is_custom("import_entity_attr"):
            error = custom_view.call_custom("import_entity_attr", None,
                                            instance, data)
            if error:
                raise RuntimeError(error)

        # Do not allow to change type when instance is already created
        if instance.pk:
            data["type"] = instance.type

        super(EntityAttrResource, self).import_obj(instance, data, dry_run)
Example #17
0
def do_edit(request, entity_id, recv_data):
    entity, error = get_obj_with_check_perm(request.user, Entity, entity_id, ACLType.Writable)
    if error:
        return error

    # validation checks
    for attr in recv_data["attrs"]:
        # formalize recv_data format
        if "ref_ids" not in attr:
            attr["ref_ids"] = []

        if int(attr["type"]) & AttrTypeValue["object"] and not attr["ref_ids"]:
            return HttpResponse("Need to specify enabled referral ids", status=400)

        if any([not Entity.objects.filter(id=x).exists() for x in attr["ref_ids"]]):
            return HttpResponse("Specified referral is invalid", status=400)

    # duplication checks
    counter = collections.Counter(
        [
            attr["name"]
            for attr in recv_data["attrs"]
            if "deleted" not in attr or not attr["deleted"]
        ]
    )
    if len([v for v, count in counter.items() if count > 1]):
        return HttpResponse("Duplicated attribute names are not allowed", status=400)

    # prevent to show edit page under the processing
    if entity.get_status(Entity.STATUS_EDITING):
        return HttpResponse("Target entity is now under processing", status=400)

    if custom_view.is_custom("edit_entity"):
        resp = custom_view.call_custom(
            "edit_entity", None, entity, recv_data["name"], recv_data["attrs"]
        )
        if resp:
            return resp

    # update status parameters
    if recv_data["is_toplevel"]:
        entity.set_status(Entity.STATUS_TOP_LEVEL)
    else:
        entity.del_status(Entity.STATUS_TOP_LEVEL)

    # update entity metatada informations to new ones
    entity.set_status(Entity.STATUS_EDITING)

    # Create a new job to edit entity and run it
    job = Job.new_edit_entity(request.user, entity, params=recv_data)
    job.run()

    new_name = recv_data["name"]
    return JsonResponse(
        {
            "entity_id": entity.id,
            "entity_name": new_name,
            "msg": 'Success to schedule to update Entity "%s"' % new_name,
        }
    )
Example #18
0
def do_delete(request, entity_id, recv_data):
    entity, error = get_obj_with_check_perm(request.user, Entity, entity_id, ACLType.Full)
    if error:
        return error

    if not entity.is_active:
        return HttpResponse("Target entity is now under processing", status=400)

    if Entry.objects.filter(schema=entity, is_active=True).exists():
        return HttpResponse(
            "cannot delete Entity because one or more Entries are not deleted",
            status=400,
        )

    if custom_view.is_custom("delete_entity"):
        resp = custom_view.call_custom("delete_entity", None, entity)
        if resp:
            return resp

    ret = {}
    # save deleting target name before do it
    ret["name"] = entity.name

    # set deleted flag in advance because deleting processing takes long time
    entity.is_active = False
    entity.save(update_fields=["is_active"])

    # Create a new job to delete entry and run it
    job = Job.new_delete_entity(request.user, entity)
    job.run()

    return JsonResponse(ret)
Example #19
0
def edit(request, entry_id):
    user = User.objects.get(id=request.user.id)
    entry, error = get_object_with_check_permission(user, Entry, entry_id, ACLType.Writable)
    if error:
        return error

    # prevent to show edit page under the creating processing
    if entry.get_status(Entry.STATUS_CREATING):
        return HttpResponse('Target entry is now under processing', status=400)

    if not entry.is_active:
        return _redirect_restore_entry(entry)

    context = {
        'entry': entry,
        'groups': Group.objects.filter(is_active=True),
        'attributes': entry.get_available_attrs(user, ACLType.Writable),
        'form_url': '/entry/do_edit/%s' % entry.id,
        'redirect_url': '/entry/show/%s' % entry.id,
    }

    if custom_view.is_custom("edit_entry", entry.schema.name):
        # show custom view
        return custom_view.call_custom("edit_entry", entry.schema.name, request, user, entry,
                                       context)
    else:
        return render(request, 'edit_entry.html', context)
Example #20
0
def edit(request, entry_id):
    entry, error = get_obj_with_check_perm(request.user, Entry, entry_id,
                                           ACLType.Writable)
    if error:
        return error

    # prevent to show edit page under the creating processing
    if entry.get_status(Entry.STATUS_CREATING):
        return HttpResponse("Target entry is now under processing", status=400)

    if not entry.is_active:
        return _redirect_restore_entry(entry)

    context = {
        "entry": entry,
        "groups": Group.objects.filter(is_active=True),
        "attributes": entry.get_available_attrs(request.user,
                                                ACLType.Writable),
        "form_url": "/entry/do_edit/%s" % entry.id,
        "redirect_url": "/entry/show/%s" % entry.id,
    }

    if custom_view.is_custom("edit_entry", entry.schema.name):
        # show custom view
        return custom_view.call_custom("edit_entry", entry.schema.name,
                                       request, request.user, entry, context)
    else:
        return render(request, "edit_entry.html", context)
Example #21
0
def do_delete(request, entry_id, recv_data):
    user = User.objects.get(id=request.user.id)
    ret = {}

    if not Entry.objects.filter(id=entry_id).exists():
        return HttpResponse('Failed to get an Entry object of specified id', status=400)

    # update name of Entry object
    entry = Entry.objects.filter(id=entry_id).get()

    if custom_view.is_custom("do_delete_entry", entry.schema.name):
        # do_delete custom view
        resp = custom_view.call_custom("do_delete_entry", entry.schema.name, request, user, entry)

        # If custom_view returns available response this returns it to user,
        # or continues default processing.
        if resp:
            return resp

    # set deleted flag in advance because deleting processing taks long time
    entry.is_active = False
    entry.save(update_fields=['is_active'])

    # save deleting Entry name before do it
    ret['name'] = entry.name

    # register operation History for deleting entry
    user.seth_entry_del(entry)

    # Create a new job to delete entry and run it
    job = Job.new_delete(user, entry)
    job.run()

    return JsonResponse(ret)
Example #22
0
def do_import_data(request, entity_id, context):
    user = User.objects.get(id=request.user.id)
    entity = Entity.objects.filter(id=entity_id, is_active=True).first()
    if not entity:
        return HttpResponse("Couldn't parse uploaded file", status=400)

    try:
        data = yaml.load(context, Loader=yaml.FullLoader)
    except yaml.parser.ParserError:
        return HttpResponse("Couldn't parse uploaded file", status=400)

    if not Entry.is_importable_data(data):
        return HttpResponse("Uploaded file has invalid data structure to import", status=400)

    if custom_view.is_custom("import_entry", entity.name):
        # import custom view
        resp = custom_view.call_custom("import_entry", entity.name, user, entity, data)

        # If custom_view returns available response this returns it to user,
        # or continues default processing.
        if resp:
            return resp

    # create job to import data to create or update entries and run it
    job = Job.new_import(user, entity, text='Preparing to import data', params=data)
    job.run()

    return HttpResponseSeeOther('/entry/%s/' % entity_id)
Example #23
0
def index(request, entity_id):
    page = request.GET.get('page', 1)
    keyword = request.GET.get('keyword', None)

    if not Entity.objects.filter(id=entity_id).exists():
        return HttpResponse('Failed to get entity of specified id', status=400)

    entity = Entity.objects.get(id=entity_id)
    if custom_view.is_custom("list_entry_without_context", entity.name):
        # show custom view without context
        resp = custom_view.call_custom("list_entry_without_context",
                                       entity.name, request, entity)
        if resp:
            return resp

    if keyword:
        name_pattern = prepend_escape_character(
            CONFIG.ESCAPE_CHARACTERS_ENTRY_LIST, keyword)
        entries = Entry.objects.order_by('name').filter(
            schema=entity, is_active=True, name__iregex=name_pattern)
    else:
        entries = Entry.objects.order_by('name').filter(schema=entity,
                                                        is_active=True)

    p = Paginator(entries, CONFIG.MAX_LIST_ENTRIES)
    try:
        page_obj = p.page(page)
    except PageNotAnInteger:
        return HttpResponse('Invalid page number. It must be unsigned integer',
                            status=400)
    except EmptyPage:
        return HttpResponse(
            'Invalid page number. The page doesn\'t have anything', status=400)

    context = {
        'entity': entity,
        'keyword': keyword,
        'page_obj': page_obj,
    }

    if custom_view.is_custom("list_entry", entity.name):
        # list custom view
        return custom_view.call_custom("list_entry", entity.name, request,
                                       entity, context)
    else:
        # list ordinal view
        return render(request, 'list_entry.html', context)
Example #24
0
    def update(self, entity: Entity, validated_data: EntityUpdateData):
        user: User = self.context["request"].user

        if custom_view.is_custom("before_update_entity_v2"):
            validated_data = custom_view.call_custom("before_update_entity_v2",
                                                     None, user,
                                                     validated_data, entity)

        return self._update_or_create(user, entity.id, validated_data)
Example #25
0
def do_import_data(request, entity_id, context):
    user: User = request.user
    entity: Entity
    entity, error = get_obj_with_check_perm(user, Entity, entity_id,
                                            ACLType.Writable)
    if error:
        return error
    if not entity.is_active:
        return HttpResponse("Failed to get entity of specified id", status=400)

    try:
        data = yaml.load(context, Loader=yaml.FullLoader)
    except yaml.parser.ParserError:
        return HttpResponse("Couldn't parse uploaded file", status=400)
    except ValueError as e:
        return HttpResponse("Invalid value is found: %s" % e, status=400)
    except yaml.scanner.ScannerError:
        return HttpResponse("Couldn't scan uploaded file", status=400)
    except Exception as e:
        return HttpResponse("Unknown exception: %s" % e, status=500)

    if not Entry.is_importable_data(data):
        return HttpResponse(
            "Uploaded file has invalid data structure to import", status=400)

    for entity_name in data.keys():
        import_entity: Entity = Entity.objects.filter(name=entity_name,
                                                      is_active=True).first()
        if not import_entity:
            return HttpResponse("Specified entity does not exist (%s)" %
                                entity_name,
                                status=400)
        if not user.has_permission(import_entity, ACLType.Writable):
            return HttpResponse("You don't have permission to access (%s)" %
                                entity_name,
                                status=400)

        import_data = data[entity_name]

        if custom_view.is_custom("import_entry", entity_name):
            # import custom view
            import_data, err_msg = custom_view.call_custom(
                "import_entry", entity_name, user, import_entity, import_data)

            # If custom_view returns available response this returns it to user,
            # or continues default processing.
            if err_msg:
                return HttpResponse(err_msg, status=400)

        # create job to import data to create or update entries and run it
        job = Job.new_import(user,
                             import_entity,
                             text="Preparing to import data",
                             params=import_data)
        job.run()

    return HttpResponseSeeOther("/entry/%s/" % entity_id)
Example #26
0
def do_copy(request, entry_id, recv_data):
    user = User.objects.get(id=request.user.id)

    # validation check
    if 'entries' not in recv_data:
        return HttpResponse('Malformed data is specified (%s)' % recv_data, status=400)

    if not Entry.objects.filter(id=entry_id).exists():
        return HttpResponse('Failed to get an Entry object of specified id', status=400)

    ret = []
    entry = Entry.objects.get(id=entry_id)
    for new_name in [x for x in recv_data['entries'].split('\n') if x]:
        if Entry.objects.filter(schema=entry.schema, name=new_name).exists():
            ret.append({
                'status': 'fail',
                'msg': 'A same named entry (%s) already exists' % new_name,
            })
            continue

        if custom_view.is_custom("do_copy_entry", entry.schema.name):
            (is_continue, status, msg) = custom_view.call_custom(
                "do_copy_entry", entry.schema.name, request, user, new_name)
            if not is_continue:
                ret.append({
                    'status': 'success' if status else 'fail',
                    'msg': msg,
                })
                continue

        params = {
            'new_name': new_name,
            'post_data': recv_data,
        }

        # Check another COPY job that targets same name entry is under processing
        if Job.objects.filter(
                operation=JobOperation.COPY_ENTRY.value,
                target=entry,
                status__in=[Job.STATUS['PREPARING'], Job.STATUS['PROCESSING']],
                params=json.dumps(params, sort_keys=True)):
            ret.append({
                'status': 'fail',
                'msg': 'There is another job that targets same name(%s) is existed' % new_name,
            })
            continue

        # make a new job to copy entry and run it
        job = Job.new_copy(user, entry, text=new_name, params=params)
        job.run()

        ret.append({
            'status': 'success',
            'msg': "Success to create new entry '%s'" % new_name,
        })

    return JsonResponse({'results': ret})
Example #27
0
def create(request, entity_id):
    entity, error = get_obj_with_check_perm(request.user, Entity, entity_id,
                                            ACLType.Writable)
    if error:
        return error

    if custom_view.is_custom("create_entry_without_context", entity.name):
        # show custom view
        return custom_view.call_custom("create_entry_without_context",
                                       entity.name, request, request.user,
                                       entity)

    context = {
        "entity":
        entity,
        "form_url":
        "/entry/do_create/%s/" % entity.id,
        "redirect_url":
        "/entry/%s" % entity.id,
        "groups":
        Group.objects.filter(is_active=True),
        "attributes": [{
            "entity_attr_id":
            x.id,
            "id":
            x.id,
            "type":
            x.type,
            "name":
            x.name,
            "is_mandatory":
            x.is_mandatory,
            "is_readble":
            True
            if request.user.has_permission(x, ACLType.Writable) else False,
        } for x in entity.attrs.filter(is_active=True).order_by("index")],
    }

    if custom_view.is_custom("create_entry", entity.name):
        # show custom view
        return custom_view.call_custom("create_entry", entity.name, request,
                                       request.user, entity, context)
    else:
        return render(request, "create_entry.html", context)
Example #28
0
def do_edit(request, entity_id, recv_data):
    user = User.objects.get(id=request.user.id)
    entity, error = get_object_with_check_permission(user, Entity, entity_id,
                                                     ACLType.Writable)
    if error:
        return error

    # validation checks
    for attr in recv_data['attrs']:
        # formalize recv_data format
        if 'ref_ids' not in attr:
            attr['ref_ids'] = []

        if int(attr['type']) & AttrTypeValue['object'] and not attr['ref_ids']:
            return HttpResponse('Need to specify enabled referral ids',
                                status=400)

        if any([
                not Entity.objects.filter(id=x).exists()
                for x in attr['ref_ids']
        ]):
            return HttpResponse('Specified referral is invalid', status=400)

    # prevent to show edit page under the processing
    if entity.get_status(Entity.STATUS_EDITING):
        return HttpResponse('Target entity is now under processing',
                            status=400)

    if custom_view.is_custom('edit_entity'):
        resp = custom_view.call_custom('edit_entity', None, entity,
                                       recv_data['name'], recv_data['attrs'])
        if resp:
            return resp

    # update status parameters
    if recv_data['is_toplevel']:
        entity.set_status(Entity.STATUS_TOP_LEVEL)
    else:
        entity.del_status(Entity.STATUS_TOP_LEVEL)

    # update entity metatada informations to new ones
    entity.set_status(Entity.STATUS_EDITING)

    # Create a new job to edit entity and run it
    job = Job.new_edit_entity(user, entity, params=recv_data)
    job.run()

    new_name = recv_data['name']
    return JsonResponse({
        'entity_id':
        entity.id,
        'entity_name':
        new_name,
        'msg':
        'Success to schedule to update Entity "%s"' % new_name,
    })
Example #29
0
    def create(self, validated_data: EntryCreateData):
        user: User = self.context["request"].user

        entity_name = validated_data["schema"].name
        if custom_view.is_custom("before_create_entry_v2", entity_name):
            validated_data = custom_view.call_custom("before_create_entry_v2",
                                                     entity_name, user,
                                                     validated_data)

        attrs_data = validated_data.pop("attrs", [])
        entry: Entry = Entry.objects.create(**validated_data,
                                            status=Entry.STATUS_CREATING)

        for entity_attr in entry.schema.attrs.filter(is_active=True):
            attr: Attribute = entry.add_attribute_from_base(entity_attr, user)

            # skip for unpermitted attributes
            if not user.has_permission(attr, ACLType.Writable):
                continue

            # make an initial AttributeValue object if the initial value is specified
            attr_data = [
                x for x in attrs_data if int(x["id"]) == entity_attr.id
            ]
            if not attr_data:
                continue
            attr.add_value(user, attr_data[0]["value"])

        if custom_view.is_custom("after_create_entry_v2", entity_name):
            custom_view.call_custom("after_create_entry_v2", entity_name, user,
                                    entry)

        # register entry information to Elasticsearch
        entry.register_es()

        # clear flag to specify this entry has been completed to create
        entry.del_status(Entry.STATUS_CREATING)

        # Send notification to the webhook URL
        job_notify_event: Job = Job.new_notify_create_entry(user, entry)
        job_notify_event.run()

        return entry
Example #30
0
def do_create(request, recv_data):
    # validation checks
    for attr in recv_data["attrs"]:
        # formalize recv_data format
        if "ref_ids" not in attr:
            attr["ref_ids"] = []

        if int(attr["type"]) & AttrTypeValue["object"] and not attr["ref_ids"]:
            return HttpResponse("Need to specify enabled referral ids",
                                status=400)

        if any([
                not Entity.objects.filter(id=x).exists()
                for x in attr["ref_ids"]
        ]):
            return HttpResponse("Specified referral is invalid", status=400)

    # duplication checks
    counter = collections.Counter([
        attr["name"] for attr in recv_data["attrs"]
        if "deleted" not in attr or not attr["deleted"]
    ])
    if len([v for v, count in counter.items() if count > 1]):
        return HttpResponse("Duplicated attribute names are not allowed",
                            status=400)

    if custom_view.is_custom("create_entity"):
        resp = custom_view.call_custom("create_entity", None,
                                       recv_data["name"], recv_data["attrs"])
        if resp:
            return resp

    # create EntityAttr objects
    entity = Entity(
        name=recv_data["name"],
        note=recv_data["note"],
        created_user=request.user,
        status=Entity.STATUS_CREATING,
    )

    # set status parameters
    if recv_data["is_toplevel"]:
        entity.status = Entity.STATUS_TOP_LEVEL

    entity.save()

    # Create a new job to edit entity and run it
    job = Job.new_create_entity(request.user, entity, params=recv_data)
    job.run()

    return JsonResponse({
        "entity_id": entity.id,
        "entity_name": entity.name,
        "msg": 'Success to create Entity "%s"' % entity.name,
    })