Luci JS: How to display status info without needing to log-in

Hello,

We are preparing to rewrite the Freifunk firmware to be compliant with Luci JS and have run into a few issues. The first of which is most likely blocking the other issues. The way the firmware has been working has been to allow unauthorized users to be able to see status/contact/statistic info of a router from anywhere on the mesh network. Perhaps the most use publicly accessible page on the mesh network is the list of neighbors and the corresponding link quality (from the OLSRd status page).

With Lua we were able to create menu entries as well as links (bottom right) with the code found in https://github.com/Freifunk-Spalter/packages/blob/master/luci/luci-mod-falter/luasrc/controller/freifunk/freifunk.lua

A co-developer and I have tried to mimic a part of this functionality with the following menu.d json entry:

{
       "unauth": {                                     
                "title": "Freifunk",                    
                "order": 10,                            
                "action": {                             
			"type": "firstchild",
			"recurse": true
                },
		"auth": {
			"methods": [ "cookie:sysauth" ],
                        "login": false
		},
		"depends": {
                        "acl": [ "luci-mod-status-logs" ]
		}
        },                                            
                                                      
        "unauth/overview": {                          
                "title": "Overview",                  
                "order": 15,                          
                "action": {                           
                        "type": "view",               
                        "path": "freifunk/index"
                },                                    
                "depends": {
                        "acl": [ "luci-mod-status-logs" ]
		}
        },                                           
                                                     
        "unauth/contact": {                          
                "title": "Contact",                  
                "order": 20,                         
                "action": {                          
                        "type": "view",              
			"path": "freifunk/index"
                },
                "depends": {
                        "acl": [ "luci-mod-status-logs" ]
		}
        }                                 
}

We are using luci-mod-status-logs as a placeholder until we write our own content.

What happens is that unless the user is logged in, nothing is shown. But as soon as the user logs in, the links on the bottom are visible and the menu entries are accessible.


(The reboot page is shown just because it is small enough to show the header and footer)

And after clicking on "Freifunk" on the bottom, the user sees this in the header:


So the question is: How can we provide the ability to have unauthorized users access the status/contact/statistic pages?

Any help would be greatly appreciated.

1 Like

Set auth to an empty object in the toplevel unauth node.

"auth": {}

I now have

{
       "unauth": {                                     
                "title": "Freifunk",                    
                "order": 10,                            
                "action": {                             
			"type": "firstchild",
			"recurse": true
                },
		"auth": { },
		"depends": {
                        "acl": [ "luci-mod-status-logs" ]
		}
        },                                            

but with the same results.

I tried rebooting. I tried logging in-and-out. Thanks for the suggestion, but do you have any other ideas?

I also noticed that if I set "order" to anything less that 10, then http://192.168.1.1/cgi-bin/luci/ shows up as a blank page. If I append "admin/" to the end of the link, I can log in again.

Blank page on order < 10 means that your "unauth" node became the default before "admin". Apparently it has nothing to display (no child nodes?). Remove the "depends": { ... } section and ensure that you have at least one unauth/something menu entry with some actual action (not firstchild). E.g. view.

The following minimal example works straight away for me:

root@er-x:~# cat /usr/share/luci/menu.d/testing-public-pages.json
{
	"public": {
		"title": "A public area",
		"order": 1,
		"action": {
			"type": "firstchild"
		},
		"auth": {}
	},

	"public/status": {
		"title": "Public status",
		"action": {
			"type": "view",
			"path": "public/test"
		}
	}
}
root@er-x:~# cat /www/luci-static/resources/view/public/test.js
'use strict';
'require view';

return view.extend({
	render: function() {
		return E('h1', 'Hello world');
	}
});

Additional hint:

The menu structure is cached in the browsers local session storage, so close/reopen the current browser tab or clear the session storage through the debugger console to avoid false/stale results while testing.

2 Likes

Thanks for the support. I have also gotten a bit further on my own, with still one issue I would like to resolve. But first I will post what I have so far so that others will have something to look at.

This json file presents two pages (currently "Hello World" pages) to an unauthorized user and as well provides the top-level menus for "Freifunk" and "Administration" at the bottom-right of the page. Clicking on "Administration" give the user the typical login screen. After logging in, the normal authorized menu system, along with a "Freifunk" menu is available.

The menus are in two different json files in /usr/share/luci/menu.d/

{
	"public": {
		"title": "Freifunk",
		"order": 5,
		"action": {
			"type": "firstchild"
		},
		"auth": { }
        },
 
	"public/overview": {
		"title": "Overview",
		"order": 10,
		"action": {
			"type": "view",
			"path": "freifunk/index"
		}
	},

	"public/contact": {
		"title": "Contact",
		"order": 20,
		"action": {
			"type": "view",
			"path": "freifunk/contact"
		}
	},

	"admin/login": {
		"title": "Login",
		"order": 999,
		"action": {
			"type": "alias",
			"path": "admin",
                },
		"auth": {
			"methods": [ "cookie:sysauth" ],
			"login": true
		}
	}
}

and

{
	"admin/freifunk": {
		"title": "Freifunk",
		"order": 5,
		"action": {
			"type": "firstchild",
			"recurse": true
		}
	},

	"admin/freifunk/status": {
		"title": "Freifunk Overview",
		"order": 1,
		"action": {
			"type": "view",
			"path": "freifunk/index"
		},
	}
}

I would say that everything looks pretty good except just one thing. Once logged into the Administration page, I can see a "Login" link on the top menu just before Logout. It's not a big deal, because clicking on it will just bring the user to the first page of the first menu. But I would prefer to get rid of it. Any help here would be appreciated.

1 Like

@jow
Hi,
I have (more or less) the same problem showing a page without login.
Although your very good example works without any problem, I would need "some kind of ACL" at this point as the page I want to show uses some rpc.declare ubus calls and a uci.get command.
With the "old" LUA version this had been no problem.
Do you have any suggestions how to solve/workaround this problem?

Thanks in advance

1 Like

Create an ACL group named „unauthenticated“ and allow the required things there. Make sure that only safe commands are allowed for unauthenticated sessions, ideally grant only read permission to uci and only allow commands without side effects.

Example:

2 Likes

@jow
Thank you for your very quick answer.
Indeed this (simple) solution solved my problem.
The only bad side is (but that will be a problem of mine): I have to patch the luci-base.json within my environment.

You don't need to patch luci-base.json, you can simply create another JSON file containing an "unauthenticated" group. The name does not need to be globally unique, it just serves as a selector for /etc/config/rpcd's read and write lists.

2 Likes

Well, that is a much more better solution.
Thank you again for your help.