emmett-framework / emmett

The web framework for inventors
BSD 3-Clause "New" or "Revised" License
1.06k stars 71 forks source link

url_prefix in App #225

Closed josejachuf closed 5 years ago

josejachuf commented 6 years ago

in reference to [1]

My proposal is to add the url_prefix parameter to the App class and make this global to the whole app.

app = App(name, url_prefix='abcd')

Although the solution proposed in the thread [1] works well, all the url() are referenced to the root of the site '/'

[1] https://groups.google.com/forum/#!topic/weppy-talk/wBx16zduh1s

gi0baro commented 6 years ago

@josejachuf have you tried naming the main module 'main'?

btw, static wouldn't follow the same prefix, this is still a problem. I'll think about this.

gi0baro commented 6 years ago

@josejachuf current master implements an option for this. I still need to add documentation for this, but if you want to try it in the meantime you can do:

app = App(__name__, url_prefix='whatever/you/prefer')

and it will be apply to every route, module and static file. Let me know, I'll keep this open until I complete the docs.

gi0baro commented 6 years ago

@josejachuf I'm sorry but this is not working properly. I should fix some issues. Will update you as soon as I complete changes.

gi0baro commented 6 years ago

@josejachuf since db903ce should be working as I described above.

josejachuf commented 6 years ago

@gi0baro What I tried works fine. Thank you very much

gi0baro commented 5 years ago

Released with 1.3

josejachuf commented 5 years ago

Hi @gi0baro

The following code allows me to sign url. It works fine, but it breaks when using url_prefix (The detail of the error commented within the code)

from weppy import Pipe, Injector, request #, abort
from weppy.expose import RouteUrl, url
from itsdangerous import Signer

KEY = 'secret-key'

class SignInjector(Injector):
    @staticmethod
    def sign(path, args, params, anchor, scheme, host, language):

        s = Signer(KEY)
        builder = RouteUrl([url(path)])
        _url = builder.url(None, None, language, args, params, None)

        # If my url_prefix is abcd, _url that I get is
        # /abcd/abcd/controller/function/arg1/arg2
        # abcd is duplicate
        # I have solved it doing the following, it works,
        # but it is a bug in the implementation of the new feature url_prefix
        _url = _url[_url.find('/',1):]

        p = _url.find('_signature')
        if p > 0:
            _url = _url[:p-1] + _url[p+38:]

        _url = str.encode(_url)
        signature = s.get_signature(_url).decode("utf-8")

        return signature

class SignPipe(Pipe):

    def pipe(self, next_pipe, **kwargs):
        if self.valid_url():
            return next_pipe(**kwargs)
        # abort(404)
        return "Resource not found"

    def valid_url(self):

        signature = request.query_params._signature or ''
        builder = RouteUrl([request.path_info])
        _url = builder.url(
            None, None, request.language, [],
            {key: request.query_params[key] for key in request.query_params.keys() if key != '_signature'},
            None)

        s = Signer(KEY)
        sig = str.encode(signature)
        value = str.encode(_url)
        return s.verify_signature(value=value, sig=sig)

Jose