Commit graph

911 commits

Author SHA1 Message Date
Franciszek Stachura
5b11f7b201 web: Add more context to error handling 2024-09-30 12:00:53 +02:00
Franciszek Stachura
36dd519b34 web: Move path parameter validation to resources 2024-09-30 12:00:53 +02:00
Théo Lebrun
e25b3d7c4b static: add /robots.txt
This is NOT being served by Elixir backend. The HTTP server in front
must serve it. Commit robots.txt to store the file somewhere.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-27 18:19:11 +02:00
Théo Lebrun
60699c4155 web: templates/layout: add favicon <link> tag
For some reason, browsers do not automatically pick up the hosted
favicon.ico available on staging server. Add an explicit line to
describe the availability of /favicon.ico.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-27 18:17:00 +02:00
Théo Lebrun
007248e61f web: static/img: commit favicon.ico
favicon.ico being served is not dependent on Elixir's configuration, but
on the front-facing server. Its config must be updated to serve the
favicon; this is why favicon.ico used to not be commited into the
repo.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-27 17:48:34 +02:00
Théo Lebrun
2eb21c82f6 web: templates/topbar: mark searchbar as required
Mark the searchbar as a required input. This avoids <Enter> on an empty
searchbar to send a "POST /$PROJECT/$VERSION/ident" with empty value,
which triggers an error.

This is made more frequent by the fact that the searchbar is
automatically focused. It also avoids implementing logic on the backend
to redirect to the previous page if an empty search was submitted.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-27 17:27:25 +02:00
Franciszek Stachura
4c0f2cf42b web: increment ?v= following script refactoring 2024-09-26 13:05:00 +02:00
Franciszek Stachura
e8f8a2e7b4 js: Switch to strict mode in script.js
The script should be compatible with strict mode, and strict mode
prevents some annoying bugs. The most important, it prevents assigning
to an undeclared variable.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
2024-09-26 13:05:00 +02:00
Franciszek Stachura
ef1b83ad75 js: Move minor fixes into functions
Move the following to new functions:
* anchor offset handler
* 301 fix
* autoscrolling prevention

Hookup onload handler with addEventListener.

About autoscrolling prevention:

I'm not sure if this is still relevant. I'm unable to trigger this
behavior. I think it could be related to a some kind of a Chrome bug.

https://forum.jquery.com/portal/en/community/topic/chrome-bug-or-how-do-i-prevent-a-form-field-to-scroll-the-container-when-focused
https://stackoverflow.com/questions/49318282/how-to-prevent-autoscroll-to-focused-input
2024-09-26 13:05:00 +02:00
Franciszek Stachura
2f7b56a4d8 js: Refactor go-to-top handler
href # doesn't work... probably because the wrapper
2024-09-26 13:05:00 +02:00
Franciszek Stachura
61ca8e19f2 js: Refactor sidebar hamburger button script
Move hamburger menu handlers to a new setup function, called from
onload.
2024-09-26 13:04:57 +02:00
Franciszek Stachura
e333b33364 js: Refactor versions tree expand/collapse script
Move versions tree handlers to a new setup function, called from
onload.
2024-09-26 12:48:34 +02:00
Franciszek Stachura
b9817c412b js: Refactor tags filter
Move tag filter setup into a new function, refactor related functions
to avoid global variables. Set up tags filter from onload handler.
2024-09-26 12:48:34 +02:00
Franciszek Stachura
f3d43c380b web: Fix sidebar state if page loaded as mobile
Fixes the following bug:

1. Make sure show-menu == true
2. Open page in mobile mode
3. Reisze to widescreen

Sidebar will be hidden until page is reloaded.
2024-09-20 15:24:59 +02:00
Franciszek Stachura
32141d8e96 web: Fix mobile sidebar close with backdrop click 2024-09-20 15:22:47 +02:00
Théo Lebrun
1aa74c4dc9 web: templates/layout.html: increment ?v= following range anchors fix
As usual, we must increment those version numbers when changes are made
to style.css and/or script.js. That purges the production cache.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-20 14:35:17 +02:00
Franciszek Stachura
c8d088834d web: Make mobile sidebar state separate
...from desktop sidebar state.

Fixes #331
2024-09-20 14:33:01 +02:00
Franciszek Stachura
9a27c7ae20 autocomplete: Submit form on item selection 2024-09-13 11:22:28 +02:00
Théo Lebrun
713401cf95 web: templates/layout.html: increment ?v= following range anchors fix
As usual, we must increment those version numbers when changes are made
to style.css and/or script.js. That purges the production cache.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-11 15:45:36 +02:00
Franciszek Stachura
b2c3ab73e9 web: Fix highlighting when second select is before first 2024-09-11 15:40:57 +02:00
Théo Lebrun
8059650f1e web: templates/layout.html: increment ?v= following range anchors
As usual, we must increment those version numbers when changes are made
to style.css and/or script.js. That purges the production cache.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-11 11:49:45 +02:00
Franciszek Stachura
30933fea6a web: Highlight whole lines of code 2024-09-11 11:48:27 +02:00
Franciszek Stachura
3b4bcd852a web: Add javascript based range links
Click line anchor and another line anchor holding shift to
make a link to a range.
2024-09-11 11:48:27 +02:00
Théo Lebrun
378dcf7e49 web: templates/layout.html: increment ?v= following sidebar changes
As usual, we must increment those version numbers when changes are made
to style.css and/or script.js. That purges the production cache.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-11 11:36:32 +02:00
Théo Lebrun
0b65c2c459 web: refactor showSidebar computation
The local storage API returns strings and has no way to set a default
value in case no value exists. We must therefore check for the "true"
string or the null value.

Let's extract it from the if boolean expression. We go from:

    if (isWidescreen && (showSidebar === "true" || showSidebar === null))

To:

    if (isWidescreen && showSidebar)

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-09-11 11:20:17 +02:00
Franciszek Stachura
0e9ff63c15 web: Save sidebar state in local storage 2024-09-11 11:13:16 +02:00
Franciszek Stachura
ec37680f04 web: Add ability to hide sidebar on desktop layout
The sidebar is hidden by default
2024-09-11 11:13:13 +02:00
Franciszek Stachura
0fed56ea25 web: Move sidebar above content
...in layout to make it load before (potentially) long source or list
of identifiers.
Reduces chances of layout shifts during load of mentioned pages.
2024-09-11 11:13:10 +02:00
Franciszek Stachura
b5d4c1ae04 web: Explicitly close Query after finishing request
API closes Query and isn't known to leak memory.
BsdDB seems to have automatic destructors, but maybe there are
some caveats.
The documentation does not say that objects have to be closed
explicitly... But it probably won't hurt. And this is the only
hint I found when trying to debug the leak so far.

https://hg.jcea.es/pybsddb/file/6.2.9/Modules/_bsddb.c#l8943
https://pybsddb.sourceforge.net/bsddb3.html
2024-09-10 10:38:52 +02:00
Franciszek Stachura
f5c7c3c1ec templates: Remove png version of logo
Backwards compatibility for browsers without svg support (in this
version) causes the logo to unnecessarily flicker on navigation.

According to caniuse.com SVG in img elements is supported in browsers
used by 97.85% of users. https://caniuse.com/svg-img
Firefox introduced support in 2011, Chrome in 2013, Safari in 2015.
2024-09-09 16:33:12 +02:00
Franciszek Stachura
8c5e12fffd Add support for 'raw' parameter for source files
This parameter makes the server return a response with raw file
contents and headers that cause the browser to show a 'save as' dialog.

Regarding Content-Security-Policy:

https://www.w3.org/TR/CSP2/#sandbox-usage

> For example, a message board or email system might provide downloads of
> arbitrary attachments provided by other users. Attacks that rely on tricking
> a client into rendering one of these attachments could be mitigated by
> requesting that resources only be rendered in a very restrictive sandbox.
> Sending the sandbox directive with an empty value establishes such an
> environment:
>
> Content-Security-Policy: sandbox

https://www.w3.org/TR/CSP2/#directive-default-src

> Given this behavior, one good way of building a policy for a site would be to
> begin with a default-src of 'none', and to build up a policy from there that
> contains only those resource types which are actually in use for the page
> you’d like to protect. If you don’t use webfonts, for instance, there’s no
> reason to specify a source list for font-src; specifying only those resource
> types a page uses ensures that the possible attack surface for that page
> remains as small as possible.

https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html#defense-in-depth

> A strong CSP provides an effective second layer of protection against various
> types of vulnerabilities, especially XSS. Although CSP doesn't prevent web
> applications from containing vulnerabilities, it can make those
> vulnerabilities significantly more difficult for an attacker to exploit.

The idea is to prevent the browser from loading any external resources, if it
turned out it's possible to trick it into interpreting a file as HTML.
2024-09-05 14:12:53 +02:00
Théo Lebrun
4058a4b4f0 web: change versions cache duration from 30m to 2m
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-08-30 20:59:08 +02:00
Franciszek Stachura
d946818e81 web: Add versions cache 2024-08-30 20:47:19 +02:00
Franciszek Stachura
00a160a154 web: Make Jinja environment global for app
This allows Jinja to cache templates between requests.
2024-08-30 16:39:32 +02:00
Théo Lebrun
ab9d776397 frontend: header: fix Bootlin logo paths and commit logo png+svg
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
2024-08-27 15:50:08 +02:00
Franciszek Stachura
6010470f3d web.py: Add error serializer, raise HTTP errors 2024-08-27 11:33:19 +02:00
Franciszek Stachura
214f606e07 README: update with information about WSGI version of Elixir
* Add changelog
2024-08-27 11:33:19 +02:00
Franciszek Stachura
287569de2f autocomplete: Validate query parameters 2024-08-27 11:33:19 +02:00
Franciszek Stachura
998f3a3da0 api, web.py: Move validators, validate API URLs 2024-08-27 11:33:19 +02:00
Franciszek Stachura
6e01f3b023 Dockerfile: update to support WSGI Elixir
* Build bsddb in a separate stage to avoid using system packages in venv
* Update Docker Apache config to support WSGI
2024-08-27 11:33:19 +02:00
Franciszek Stachura
9e18f26aeb Restructure Elixir to avoid Python path hacks
* Move static files from http to a new directory
2024-08-27 11:33:18 +02:00
Franciszek Stachura
584c98686d Move get_query to query.py
Refactor api and autocomplete to use it and properly handle errors
related to invalid project names.
2024-08-27 11:32:19 +02:00
Franciszek Stachura
1ace9f746f api: Move to main application 2024-08-27 11:32:19 +02:00
Franciszek Stachura
4f03a83287 autocomplete: Move to main application 2024-08-27 11:32:19 +02:00
Franciszek Stachura
2a7119fcff autocomplete: Make faster by utilizing DB_SET_RANGE
for prefix search

https://stackoverflow.com/questions/12348346/berkeley-db-partial-match

This *should* return the same results as the original autocomplete.

Steps the original autocomplete takes to find identifiers:
1. It dumps all keys using db.keys() into a file
    query.py:Query.query('keys')
    data.py:BsdDB.get_keys()
    https://pybsddb.sourceforge.net/bsddb3.html - keys(txn=None)
github.com/virtuozzo/cdn-bsddb3-python/blob/fbb1a877/Lib3/bsddb/dbobj.py#L171
github.com/virtuozzo/cdn-bsddb3-python/blob/fbb1a877/Modules/_bsddb.c#L8565
github.com/virtuozzo/cdn-bsddb3-python/blob/fbb1a877/Modules/_bsddb.c#L3730
    seems that this just iterates over the db calling get with DB_NEXT
    on the cursor
    https://docs.oracle.com/cd/E17276_01/html/api_reference/C/dbcget.html
2. Iterates over the keys, looking for keys that start with provided string.
    The script stops when it finds 10 items.

So it's assumed that the order of keys returned by get(DB_NEXT) will make
sense.

This version finds the first key that starts with the prefix using
get(DB_SET_RANGE) and then, just like the previous autocomplete,
iterates over the keys until it finds 10 matching keys.
Now, could get(DB_SET_RANGE) skip keys (ex. point to some other key than
the first key that starts with the prefix)?
I think not - according to the docs, it should point to "the smallest key
greater than or equal to the specified key". The comparison function
determines what "greater or equal" means.
The default comparison function compares keys lexically, with shorter
keys before longer keys.

https://docs.oracle.com/cd/E17276_01/html/api_reference/C/dbset_bt_compare.html

I believe, although I couldn't find precise information about this,
that order of keys when using DB_SET_RANGE shouldn't change.

So tl;dr I'm mostly sure this should work the same way as it worked
before, just faster. There could still be issues with how keys are
ordered in results. The default function seems to just order
characters by byte values.

github.com/berkeleydb/libdb/blob/master/src/btree/bt_compare.c#L154

Also, this allows identifiers sent to autocomplete to contain commas.
2024-08-27 11:32:19 +02:00
Franciszek Stachura
4174b85f2d autocomplete: Move to Falcon 2024-08-27 11:32:19 +02:00
Franciszek Stachura
bcc76c521b web.py: Refactor to use the Falcon framework
* Add requirements.txt with packages used by WSGI Elixir
* Make API compatible with latest Falcon
* Remove remaining global variables from web.py
* Remove Parsed__Path

Falcon passes parsed path segments as arguments to handler methods.
I think it really does not make sense anymore to put that information
back into a tuple just to unpack it again.

* Add RawPathComponent middleware to support encoded slashes

Some paths previously accepted by Elixir can contain encoded slashes.
For example:
/arm-trusted-firmware/sandbox%2Flts-v2.10.3-20240405T0714/source

Falcon by default uses a version of URL that is already decoded. This
default makes parsing said paths impossible.

https://falcon.readthedocs.io/en/v3.1.2/user/recipes/raw-url-path.html

* Move request context building to middleware
* Move validation and unquoting to path converters
* Move base url generation to new functions
2024-08-27 11:32:17 +02:00
Franciszek Stachura
e8da1bf578 Reduce sidebar flashing on navigation
by moving some dynamic HTML generation to templates.
Also fixes no-js CSS a bit by hiding useless elements.
2024-08-20 14:32:52 +02:00
Franciszek Stachura
7d629429bf Generate different meta tag descriptions for different views
Added an ability to customize contents of meta description tag in
templates that inherit from layout. This replaces the default
description previously used in all views.
This change could help with SEO and missing descriptions in search
results (#167). It's based on advice from
https://developers.google.com/search/docs/appearance/snippet

> Create unique descriptions for each page on your site
> Programmatically generate descriptions

This is not guaranteed to fix the issue, search engines are opaque.

All custom descriptions start with "Elixir Cross Referencer - ".

Currently customized descriptions:
* source - path to the file, project name and version
* ident - name of the searched identifier, project name and version

Everything else uses the previous, default description.
2024-08-20 10:35:17 +02:00
Franciszek Stachura
43b4f720b4 Prefer GAS Lexer for .S files
Currently, Pygments often picks SLexer for .S files. It's a lexer for
files related to the R language.

https://pygments.org/docs/lexers/#pygments.lexers.r.SLexer

```
>>> import pygments.lexers
>>> pygments.lexers.guess_lexer_for_filename('arch/x86/boot/header.S',
        open('arch/x86/boot/header.S').read())
<pygments.lexers.SLexer>
```

This commits makes sure Elixir prefers the GAS lexer for .S files
instead of SLexer.
It's not the best heuristic, but better than picking the SLexer class
sometimes.
Currently, Elixir does not index any R language projects. In the future,
it would be better to specify per-project information about what
languages are used.
2024-08-20 10:34:58 +02:00