GithubHelp home page GithubHelp logo

hivesolutions / appier-extras Goto Github PK

View Code? Open in Web Editor NEW
2.0 4.0 3.0 2.81 MB

Appier on Steroids

Home Page: http://appier-extras.hive.pt

Python 76.18% JavaScript 0.97% CSS 1.78% Smarty 21.07%
appier appier-extras addon

appier-extras's People

Contributors

3rdvision avatar beemargarida avatar gcandal avatar hugo-gomes avatar joamag avatar tsilva avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

appier-extras's Issues

Support for socket.io like websockets

Description

Creating a websocket like real-time communication is currently very hard under the Appier environment.
It should be possible to do this kind of integration for the Tasks abstractions of the appier_admin infra-structure.

This issue is related to hivesolutions/appier#25

Implemenation

This feature should take inspiration in other node based implementations like Socket.io.

OAuth support for authentication

Description

It should be possible to activate a feature in the login/authentication part of Appier Extras allowing external authentication to take place using OAuth. This would allow easy integration of OAuth for Apps using Appier Extras.

This feature is related with hivesolutions/appier#29.

Implementation

There should be a simple workflow allowing proper authentication.

Support for inserting arrays in admin

Description

Currently when I insert data for an item of list type it's converted and saved as an array with one string. In the admin interface it appears correctly:

screenshot 2015-09-25 16 29 25

But when I retrieve the data itself, the items were turned into a string:

screenshot 2015-09-25 16 30 11

Suport for advanced searching in model listing

Description

Currently there's no way of searching "inside" a specific model in the appier admin interface, that's relevant to be able to properly explore data.

Inspiration

Omni entity advanced search

Images

search

Dynamic inclusion of parts with the PARTS configuration value

Description

Sometimes it's important to be able control the Parts that are included on a app dynamically at runtime. To be able to archive this a list based configuration variable must be used appier.conf("PARTS", cast = list).

The parts definition should be something like appier_extras.AdminPart and the appier_extras packages should be included dynamically using the appier.import_pip(appier_extras) this way it would be possible to include the admin part without setting appier extras on dependencies.

`resize_image` `get_data()` method throwing

Bug description

When defining a resizable image for e.g with:

            avatar_data = utils.resize_image(
                avatar.data, etag=avatar.etag, width=width, height=height
            )

and later calling to get the output data using:

output_data = avatar_data.get_data()

it will throw the error `cannot access local variable 'resample':

UnboundLocalError

500 - cannot access local variable 'resample' where it is not associated with a value
File "/home/pc1/.local/lib/python3.11/site-packages/appier/base.py", line 1560, in application_l
result = self.handle()
File "/home/pc1/.local/lib/python3.11/site-packages/appier/base.py", line 1761, in handle
result = self.route()
File "/home/pc1/.local/lib/python3.11/site-packages/appier/base.py", line 2054, in route
return_v = method_i(*args, **kwargs)
File "/home/pc1/Documents/ripe-tech/ripe-id/src/ripe_id/controllers/web/account.py", line 171, in avatar
return account._send_avatar(
File "/home/pc1/.local/lib/python3.11/site-packages/appier_extras/parts/admin/models/account.py", line 697, in _send_avatar
return self.owner.send_file(
File "/home/pc1/.local/lib/python3.11/site-packages/appier/base.py", line 2945, in send_file
contents = contents()
File "/home/pc1/.local/lib/python3.11/site-packages/appier_extras/utils/image.py", line 63, in get_data
if resample == None:

Details

This is related to a recent change.

Although the logic implemented makes sense and initially the method defines resample=None in the python's locals, when we call the inner get_data method, the resample is no longer defined, probably due to a strange unexpected python interpreter response that cleans up the variable thinking it won't be used.

This was later verified to be true by changing the if resample == None: resample = (...) to something else to not trick python interpreter into thinking that resample will always be defined.

I think this is a very strange behavior and might be a python issue.

Incoming PR with a working fix suggestion.

Environment

Python 3.11.6

Param support in the operation parameters

Description

Currently operation parameters are described as a simple tuple instance. A new appier.param() structure must be creating inheriting from tuple and adding new functionaly, like named parameters.

Use cases

Using it to provide support for the placeholder value (eg: appier.param("name", placeholder = "Your name"))

0

Model CRUD operations not working as expected

Description

The model CRUD operations are not working as expected.

Expected vs. Observed

- -
Expected A model/entity can be created through /api/admin/models/<str:model>
Observed The POST /api/admin/models/<str:model> request returns the result for GET /api/admin/models

Repro Steps

  1. Create a POST request with the URL http://ripe-core-now.platforme.com/api/admin/models/events
  2. Authenticate (ex: secret key)
  3. Use the following JSON as example for the request:
{
    "name": "order.created.swear",
    "description": "order.created.swear",
    "handler": "http",
	"arguments": {
		"name_r": "Order created #{params[payload][number]}",
		"sender": "Platforme Reports <[email protected]>",
		"title": "Order Created created #{params[payload][number]}",
		"receivers": ["[email protected]"],
		"subject": "Swear Order Created: #{params[payload][number]}"
	}
}
  1. Verify that the result is a list of 10 of the existing models (the expected response for GET /api/admin/models

Environment

Key Value
Device iMac
Operating System macOS Catalina
Instance (URL) RIPE CORE NOW

Screens

Notes

  • There is a similar issue with the update and delete, as both of them return the expected result of the GET of the same request (info of that model).
  • I can't seem to reproduce any of this in the local environment, with everything(as far as I know) up to date.
  • Everything is working locally, with the only changes to the request being the URL and the secret key.

Multiple logins at the same time

Descriptions

It may be relevant to keep multiple logins at the same time for fast switching.

Implementation

The feature should be enabled or disabled using the ADMIN_MULTI_USER config variable.

  • ADMIN_MULTI_USER (bool) - Controls if the multiple user login support should be enabled or not (defaults to True)

The overall implementation idea should follow the Omni guidelines.

capture

Debug toolbar

Description

A simple toolbar to be included in DEBUG mode so that some extra debug information (eg: SQL execution time, render time, queries, etc.) may be displayed and used.

Screens

02_django_debug_toolbar_collapsed

References

Multidimensional storage of an entity

Description

Sometimes it's relevant to keep storing the history/snapshot of an entity as backup that may be used latter to rollback unwanted changes.

For that a pre_update (and pre_delete) operation must be created that intercepts the storage operation and that retrieves a snapshot of the current state storing it on a different collection.

There should be a proper UI for retrieval (and inspection) of a different snapshot (snapshots collection).

Two Factor (2FA) authentication

Description

Sometimes, it's relevant to increase the security of the authentication process by using 2FA, for instance, with a one-time password.

The additional layer of security can prevent attacks from malicious agents using a brute force password-targeted attack,

Implementation

Some libraries for Python can handle the hardcore work (e.g., pyotp).

Inspiration

Code

OTP Example

According to ChatGPT, this would be a valid implementation for a OTP based approach (eg: Google Authenticator).

import pyotp

def generate_secret():
    # This will generate a fresh secret key
    secret = pyotp.random_base32()
    print(f"Secret key for user: {secret}")
    return secret

def generate_otp(secret):
    # Generate a TOTP object
    totp = pyotp.TOTP(secret)
    return totp.now()  # Generate a OTP based on the current time

def verify_otp(secret, user_input):
    # Verifies user input against the current OTP
    totp = pyotp.TOTP(secret)
    return totp.verify(user_input)

# Usage
user_secret = generate_secret()
otp = generate_otp(user_secret)
print(f"Generated OTP: {otp}")

# Simulate user entering OTP
user_otp_input = input("Enter the OTP: ")
if verify_otp(user_secret, user_otp_input):
    print("OTP is correct!")
else:
    print("Invalid OTP.")

FIDO2 Example

Server side

from fido2.webauthn import PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity
from fido2.server import Fido2Server
from fido2.client import ClientData
from fido2.ctap2 import AttestationObject, AuthenticatorData
from fido2 import cbor

# Setup the relying party information
rp = PublicKeyCredentialRpEntity(name="Example Corp", id="localhost")

# User information (this should be dynamic in production use)
user = PublicKeyCredentialUserEntity(id=b"user_id", name="[email protected]", display_name="User")

# Initialize the server with the relying party details
server = Fido2Server(rp)

# Registration
def register_begin():
    registration_data, state = server.register_begin({
        "id": user.id,
        "name": user.name,
        "displayName": user.display_name,
    })
    return cbor.encode(registration_data), state

def register_complete(client_data, attestation_object, state):
    client_data = ClientData(client_data)
    attestation_obj = AttestationObject(attestation_object)
    auth_data = server.register_complete(state, client_data, attestation_obj)
    return auth_data.credential_data

# Authentication
def authenticate_begin():
    auth_data, state = server.authenticate_begin(user)
    return cbor.encode(auth_data), state

def authenticate_complete(client_data, authenticator_data, state):
    client_data = ClientData(client_data)
    auth_data = AuthenticatorData(authenticator_data)
    server.authenticate_complete(state, user, client_data, auth_data)
    return "Authentication successful!"

Client Side

# Simulate client operations for registration
client_data_json, state = register_begin()
# Normally client_data_json would be used by the client with the user's security key.
# For this example, assume we get the following from the client/security key.
client_data = b"{}"  # Example client data, should be obtained from the security key
attestation_object = b"{}"  # Example attestation object, should be obtained from the security key

# Complete registration
credential_data = register_complete(client_data, attestation_object, state)
print("Registration complete. Credential data:", credential_data)

# Simulate client operations for authentication
auth_data, state = authenticate_begin()
# Again, assume we get the necessary data from the client/security key.
client_data = b"{}"
authenticator_data = b"{}"

# Complete authentication
result = authenticate_complete(client_data, authenticator_data, state)
print(result)

Exception tracing for production environment with exception code (SHA 256)

Description

Under production environments the stack-trace (error log) cannot be displayed directly to the end-user (user-agent) because of privacy issues.

The proper way to handle this is to store the stack trace (and other error information) in an external database and then provide the end-user user with an error tracing code (SHA 256) so that he can provide that to customer service and have the error diagnosed.

Solution

  • Rely on an external service like Opbeat to do that
  • Implement our own solution and use a client on Appier Extras
  • Create an entity named Exception that stores all of this information in the data store

Library version in the status page

Description

In order to properly debug the various libraries loaded in the python runtime (eg: pillow, pymongo, etc) there should be an inverted system that automatically determines the various loaded modules and gathers the version numbers.

The implementation should be as simple and isolated as possible (may have to change the appier).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.