Front-end stream form error when logged out

twopiers - 9 months ago

Hi everyone, hoping you can help me solve an issue. Clearly I did something wrong here.

I created a stream, defined the fields, etc. All good. One of the fields is a file field type. I then created a front-end form following Ryan’s video. Code looks something like this ("abstractions" is my module name and stream name):

{% set form = form('abstractions', 'abstractions').actions(['submit']).get() %}
{{ form.open|raw }}
{% for field in form.fields %}
    {{ field.label }}:{% if field.required %}<sup>*</sup>{% endif %}
    {{ field.input|raw }}
{% endfor %}
{{ form.close|raw }}

If I’m logged into the Admin and view the front-end form, looks and works great. If I’m logged out of the Admin, I get an error that seems to be coming from the file field type input.twig file (line 14: {{ field_type.value_table|raw }}). A little further down the stack trace it references TableAuthorizer class. Did I miss something regarding permissions?

Thanks!

ryanthompson - 9 months ago

Can you post the stack trace?

twopiers - 9 months ago

You bet:

ErrorException 
…/addons/default/twopiers/abstractions-module/resources/views/form.twig129
119
Twig_Error_Runtime 
…/vendor/twig/twig/lib/Twig/Template.php182
118
ErrorException 
…/core/anomaly/file-field_type/resources/views/input.twig14
117
Twig_Error_Runtime 
…/vendor/twig/twig/lib/Twig/Template.php402
116
Symfony\Component\HttpKernel\Exception\HttpException 
…/vendor/laravel/framework/src/Illuminate/Foundation/Application.php917
115
Illuminate\Foundation\Application abort
…/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php31
114
 abort
…/vendor/anomaly/streams-platform/src/Ui/Table/TableAuthorizer.php43
113
Anomaly\Streams\Platform\Ui\Table\TableAuthorizer authorize
…/vendor/anomaly/streams-platform/src/Ui/Table/Command/AuthorizeTable.php40
112
Anomaly\Streams\Platform\Ui\Table\Command\AuthorizeTable handle
…/vendor/laravel/framework/src/Illuminate/Container/Container.php508
111
 call_user_func_array
…/vendor/laravel/framework/src/Illuminate/Container/Container.php508
110
Illuminate\Container\Container call
…/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php94
109
Illuminate\Bus\Dispatcher Illuminate\Bus\{closure}
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php151
108
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php104
107
Illuminate\Pipeline\Pipeline then
…/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php98
106
Illuminate\Bus\Dispatcher dispatchNow
…/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php75
105
Illuminate\Bus\Dispatcher dispatch
…/vendor/laravel/framework/src/Illuminate/Foundation/Bus/DispatchesJobs.php17
104
Anomaly\Streams\Platform\Ui\Table\Command\BuildTable dispatch
…/vendor/anomaly/streams-platform/src/Ui/Table/Command/BuildTable.php72
103
Anomaly\Streams\Platform\Ui\Table\Command\BuildTable handle
…/vendor/laravel/framework/src/Illuminate/Container/Container.php508
102
 call_user_func_array
…/vendor/laravel/framework/src/Illuminate/Container/Container.php508
101
Illuminate\Container\Container call
…/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php94
100
Illuminate\Bus\Dispatcher Illuminate\Bus\{closure}
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php151
99
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php104
98
Illuminate\Pipeline\Pipeline then
…/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php98
97
Illuminate\Bus\Dispatcher dispatchNow
…/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php75
96
Illuminate\Bus\Dispatcher dispatch
…/vendor/laravel/framework/src/Illuminate/Foundation/Bus/DispatchesJobs.php17
95
Anomaly\Streams\Platform\Ui\Table\TableBuilder dispatch
…/vendor/anomaly/streams-platform/src/Ui/Table/TableBuilder.php134
94
Anomaly\Streams\Platform\Ui\Table\TableBuilder build
…/core/anomaly/file-field_type/src/FileFieldType.php141
93
Anomaly\FileFieldType\FileFieldType valueTable
…/vendor/anomaly/streams-platform/src/Support/Presenter.php80
92
 call_user_func_array
…/vendor/anomaly/streams-platform/src/Support/Presenter.php80
91
Anomaly\Streams\Platform\Support\Presenter __get
…/vendor/anomaly/streams-platform/src/Addon/FieldType/FieldTypePresenter.php80
90
Anomaly\Streams\Platform\Addon\FieldType\FieldTypePresenter __get
…/vendor/robclancy/presenter/src/Presenter.php97
89
Robbo\Presenter\Presenter offsetGet
…/vendor/twig/twig/lib/Twig/Template.php475
88
Twig_Template getAttribute
…/vendor/rcrowe/twigbridge/src/Twig/Template.php129
87
TwigBridge\Twig\Template getAttribute
…/storage/framework/views/twig/e7/e7571b45bd5fb05dc981ba8219411558778f9375f4e480d3a99013f5fa5c9ece.php76
86
__TwigTemplate_3ef45b23d801cde74c77bc05b9f06a1cff3583f37838810bc9faf210f6c5f5a5 doDisplay
…/vendor/twig/twig/lib/Twig/Template.php387
85
Twig_Template displayWithErrorHandling
…/vendor/twig/twig/lib/Twig/Template.php355
84
Twig_Template display
…/vendor/rcrowe/twigbridge/src/Twig/Template.php41
83
TwigBridge\Twig\Template display
…/vendor/twig/twig/lib/Twig/Template.php366
82
Twig_Template render
…/vendor/rcrowe/twigbridge/src/Engine/Twig.php90
81
TwigBridge\Engine\Twig get
…/vendor/laravel/framework/src/Illuminate/View/View.php149
80
Illuminate\View\View getContents
…/vendor/laravel/framework/src/Illuminate/View/View.php120
79
Illuminate\View\View renderContents
…/vendor/laravel/framework/src/Illuminate/View/View.php85
78
Illuminate\View\View render
…/vendor/anomaly/streams-platform/src/Addon/FieldType/FieldType.php1163
77
Anomaly\Streams\Platform\Addon\FieldType\FieldType getInput
…/vendor/anomaly/streams-platform/src/Addon/Addon.php344
76
Anomaly\Streams\Platform\Addon\Addon __get
…/vendor/twig/twig/lib/Twig/Template.php542
75
Twig_Template getAttribute
…/vendor/rcrowe/twigbridge/src/Twig/Template.php129
74
TwigBridge\Twig\Template getAttribute
…/storage/framework/views/twig/bb/bb48f20429677de1b0bfdedcaf58408cb3bd40b13adbb6acc8cb05b0c8ef5504.php180
73
__TwigTemplate_c1af866410c825ec0efe60f62f8931444712a85cd49917de6294ca8f989af3c0 block_content
…/vendor/twig/twig/lib/Twig/Template.php167
72
Twig_Template displayBlock
…/storage/framework/views/twig/f6/f68c4fe5ac3cbc0697f2cc8eccd7949fc7e70892b6d0b10396288754564e07a6.php38
71
__TwigTemplate_5b816f43c526f176f8bece42eb8731eac75c6ae66d9fa6a69838c49c2926185e doDisplay
…/vendor/twig/twig/lib/Twig/Template.php387
70
Twig_Template displayWithErrorHandling
…/vendor/twig/twig/lib/Twig/Template.php355
69
Twig_Template display
…/vendor/rcrowe/twigbridge/src/Twig/Template.php41
68
TwigBridge\Twig\Template display
…/storage/framework/views/twig/bb/bb48f20429677de1b0bfdedcaf58408cb3bd40b13adbb6acc8cb05b0c8ef5504.php24
67
__TwigTemplate_c1af866410c825ec0efe60f62f8931444712a85cd49917de6294ca8f989af3c0 doDisplay
…/vendor/twig/twig/lib/Twig/Template.php387
66
Twig_Template displayWithErrorHandling
…/vendor/twig/twig/lib/Twig/Template.php355
65
Twig_Template display
…/vendor/rcrowe/twigbridge/src/Twig/Template.php41
64
TwigBridge\Twig\Template display
…/vendor/twig/twig/lib/Twig/Template.php366
63
Twig_Template render
…/vendor/rcrowe/twigbridge/src/Engine/Twig.php90
62
TwigBridge\Engine\Twig get
…/vendor/laravel/framework/src/Illuminate/View/View.php149
61
Illuminate\View\View getContents
…/vendor/laravel/framework/src/Illuminate/View/View.php120
60
Illuminate\View\View renderContents
…/vendor/laravel/framework/src/Illuminate/View/View.php85
59
Illuminate\View\View render
…/vendor/laravel/framework/src/Illuminate/Http/Response.php45
58
Illuminate\Http\Response setContent
…/vendor/symfony/http-foundation/Response.php201
57
Symfony\Component\HttpFoundation\Response __construct
…/vendor/laravel/framework/src/Illuminate/Routing/Router.php1028
56
Illuminate\Routing\Router prepareResponse
…/vendor/laravel/framework/src/Illuminate/Routing/Router.php654
55
Illuminate\Routing\Router Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php53
54
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/anomaly/streams-platform/src/Http/Middleware/CheckForMaintenanceMode.php76
53
Anomaly\Streams\Platform\Http\Middleware\CheckForMaintenanceMode handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
52
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
51
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/anomaly/streams-platform/src/Http/Middleware/ApplicationReady.php49
50
Anomaly\Streams\Platform\Http\Middleware\ApplicationReady handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
49
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
48
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/anomaly/streams-platform/src/Http/Middleware/SetLocale.php88
47
Anomaly\Streams\Platform\Http\Middleware\SetLocale handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
46
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
45
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/anomaly/streams-platform/src/Http/Middleware/PoweredBy.php38
44
Anomaly\Streams\Platform\Http\Middleware\PoweredBy handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
43
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
42
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php65
41
Illuminate\Foundation\Http\Middleware\VerifyCsrfToken handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
40
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
39
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/core/anomaly/users-module/src/Http/Middleware/AuthorizeRoutePermission.php107
38
Anomaly\UsersModule\Http\Middleware\AuthorizeRoutePermission handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
37
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
36
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/core/anomaly/users-module/src/Http/Middleware/AuthorizeControlPanel.php44
35
Anomaly\UsersModule\Http\Middleware\AuthorizeControlPanel handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
34
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
33
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/core/anomaly/users-module/src/Http/Middleware/AuthorizeModuleAccess.php54
32
Anomaly\UsersModule\Http\Middleware\AuthorizeModuleAccess handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
31
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
30
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/core/anomaly/users-module/src/Http/Middleware/AuthorizeRouteRoles.php106
29
Anomaly\UsersModule\Http\Middleware\AuthorizeRouteRoles handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
28
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
27
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/core/anomaly/users-module/src/Http/Middleware/CheckSecurity.php86
26
Anomaly\UsersModule\Http\Middleware\CheckSecurity handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
25
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
24
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php104
23
Illuminate\Pipeline\Pipeline then
…/vendor/laravel/framework/src/Illuminate/Routing/Router.php655
22
Illuminate\Routing\Router runRouteWithinStack
…/vendor/laravel/framework/src/Illuminate/Routing/Router.php629
21
Illuminate\Routing\Router dispatchToRoute
…/vendor/laravel/framework/src/Illuminate/Routing/Router.php607
20
Illuminate\Routing\Router dispatch
…/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php268
19
Illuminate\Foundation\Http\Kernel Illuminate\Foundation\Http\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php53
18
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/barryvdh/laravel-debugbar/src/Middleware/Debugbar.php51
17
Barryvdh\Debugbar\Middleware\Debugbar handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
16
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
15
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php49
14
Illuminate\View\Middleware\ShareErrorsFromSession handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
13
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
12
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php64
11
Illuminate\Session\Middleware\StartSession handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
10
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
9
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php37
8
Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
7
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
6
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php59
5
Illuminate\Cookie\Middleware\EncryptCookies handle
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php137
4
Illuminate\Pipeline\Pipeline Illuminate\Pipeline\{closure}
…/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php33
3
Illuminate\Routing\Pipeline Illuminate\Routing\{closure}
…/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php104
2
Illuminate\Pipeline\Pipeline then
…/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php150
1
Illuminate\Foundation\Http\Kernel sendRequestThroughRouter
…/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php117
0
Illuminate\Foundation\Http\Kernel handle

twopiers - 9 months ago

Hey Ryan, not sure this will help, but here is the module migration file $fields definition:

protected $fields = [
        'name' => 'anomaly.field_type.text',
        'company' => 'anomaly.field_type.text',
        'title' => 'anomaly.field_type.text',
        'phone' => 'anomaly.field_type.text',
        'email' => 'anomaly.field_type.email',
        'speaker_name' => 'anomaly.field_type.text',
        'speaker_company' => 'anomaly.field_type.text',
        'speaker_title' => 'anomaly.field_type.text',
        'speaker_phone' => 'anomaly.field_type.text',
        'speaker_email' => 'anomaly.field_type.email',
        'session_type' => [
            'type'     => 'anomaly.field_type.select',
            'config'   => [
                'options' => [
                    'Workshops' => 'Workshops',
                    'Keynotes' => 'Keynotes',
                    'Panel' => 'Panel',
                    'Presentation' => 'Presentation',
                ],
                "default_value" => null,
                "mode"          => "radio",
            ]
        ],
        'abstract_title' => 'anomaly.field_type.text',
        'description' => 'anomaly.field_type.textarea',
        'speakers' => 'anomaly.field_type.textarea',
        'speaker_image' => [
            'type' => 'anomaly.field_type.file',
            "config" => [
                "default_value" => null,
                "folders"       => ['abstract_images'],
                "max"           => null,
                "mode"          => "upload",
            ],
        ]
    ];

ryanthompson - 9 months ago

Ok so in \Anomaly\Streams\Platform\Ui\Table\TableAuthorizer it looks like the permission is getting set by default because.. well that's default behavior. Forms behave similarly but because this is a core table (Files module / files stream) it's actually finding a permission and testing it.

I feel like the permissions should only be set by default if in the control panel - otherwise it's up to you to explicitly define them.

Thoughts?

ryanthompson - 9 months ago

Like.. if you're displaying this on the front end that's an explicit action - you're going out of your way to do it.

twopiers - 9 months ago

It's a front-end form that should be publicly available, by default in my humble opinion, but maybe (probably) I'm not understanding your meaning. I build a stream that I want the public to populate via a front-end form without registering as a user. I think that's pretty common, at least in my world. This is basically a "contact us" form with some additional requirements (the file being one of them).

That said, it's your software and I will happily play by your rules. I don't mind explicitly setting permissions, I just have no idea how to do that.

stevenweijdt - 9 months ago

Two things to keep in mind. You need to protect the user (especially the rookies) for any defaults that are dangerous. At the same time.. you should make the number one use case a default.

Permissions in the backend are probably more obvious. You have so many settings a lot of admins are not allowed to touch.. so every serious super admin would set that up correctly with a bit more effort and focus. Also a lot of cases there's just one admin.

On the frontend however, two use cases.

  1. certain type of user can upload files
  2. a guest (so everybody) can upload files

I would go for option 2. But put a big warning and info text in the admin area about permissions. So people know they should be looking at the docs and permissions, in case their use case needs protection.

ryanthompson - 9 months ago

The thing is this is strictly default behavior. @twopiers you can set permissions in protected $options = ['permission' => $permissionString];

Permissions were originally intended for UI builders (and works wonderfully) because the UI builders are providing the response. In the case of including the form in your view it's no longer the response but instead content. So your controller / page or whatever should be responsible for authorizing IMO. I am going to modify the defaults @twopiers so your code should work as expected on the front end.

@stevenweijdt good point on protecting users though.. I have some modifications to a string cleaning function / comments module & forum I think that will make this more responsible on my end in protecting more by default.

Thanks guys!

ryanthompson - 9 months ago

@twopiers all set.

twopiers - 9 months ago

Just updated, works perfectly. Thanks Ryan! Based on your response, should I be doing this in a different way? Given these parameters, I'm genuinely interested to know how you would approach this? What is best practice?

  1. public facing form, no login/registration required
  2. optional image upload
  3. viewable responses in the Admin

Again, thanks Ryan. Very much appreciated!