Repository navigation
feat(service_adguard_home): add AdGuard Home support - #180
Merged
Merged
Conversation
… no password AdGuard Home counts every wrong Authorization: Basic header as a failed sign-in, on any path, and refuses the address for fifteen minutes after five, right password included. Measured on v0.107.79; requests with no credentials do not count. So the health probe for this kind leaves with no Authorization header at all, neither the instance's own nor one the profile's custom headers set, and reads a 401 as a server that is up. The dot cannot tell a wrong password from a right one, which is the price of not locking the owner out of their own web UI twice a minute. Everything else is signed with HTTP Basic when credentials were entered, and with nothing when they were not: a server set up without a user answers anyone.
A new package, with the models the Home tab and the dashboard widget need and the formatting they share. The fixtures are what v0.107.79 answered. The models are read by hand rather than generated: a top list arrives as a list of one-entry objects, and the server sends null where it means an empty list.
…refused sign-in AdGuard Home refuses an address for fifteen minutes after five wrong sign-ins, and answers the right password with the same bare 401 while it does. Every signed request counts. So requests to an instance queue behind one another: when the first is refused, the ones waiting fail without being sent. After a refusal nothing is sent at all until the user asks to try again, which costs one more request. The client covers what the Home tab and the dashboard widget read and write: status, statistics, the filter lists, the statistics period, protection with an optional pause, and the custom rules.
…y its web UI does Providers for the status (every 10 seconds), the statistics (30), the filter lists (5 minutes) and the statistics period, all through the instance's one session, so a refused sign-in is still a single request however many of them are being watched, and however often Riverpod's own retries or the poll come round again. Blocking or unblocking a domain follows the web UI's own steps: an opposite custom rule is removed if there is one, and only otherwise is ||domain^$important or its @@ form appended. The rules are read fresh before the write, which replaces the whole list. The pauses are the five the web UI offers; its "until tomorrow" is a flat 24 hours.
Protection with a switch and the five pauses the web UI offers, a countdown while paused, the six figures with their series, and the top lists. A queried domain can be blocked and a blocked one unblocked from its row. The countdown runs on the device between polls and asks the server again the moment it reaches zero, so a finished pause is not left on screen until the next poll. Once the server has refused the sign-in, the tab shows why and what AdGuard Home does about wrong tries, and sends nothing more until Try again is tapped.
The health probe carries no password for AdGuard Home, so Test connection signs in once itself. A refusal says that the server, by default, blocks an address for 15 minutes after five wrong tries. An address that answers with something other than AdGuard Home's API says that instead of calling the server unreachable. The form tests the local address and then the external one, and each wrong password counts towards that lockout. So a sign-in refused in the last 30 seconds is not sent again unless something on the form changed, and the result says it was not tried. The form no longer demands a username and password for it: a server set up without a user answers anyone.
One block per instance: whether it is protecting, a menu to pause it for one of the lengths AdGuard Home's own page offers or to turn it off, Resume while it is paused or off, and four figures: queries, blocked, the blocked share, and the rules on the enabled blocklists. A refused sign-in is said in place, with what AdGuard Home does about wrong tries, and is tried again only when asked.
AdGuard Home returns rows of equal count in a different order on every read. Shown as they arrived, tied rows in the top lists swapped places at each poll, and a tap on Block could land on a different domain than the one aimed at. Ties are now settled by name.
When one tile's label took more lines than its neighbour's, the shorter tile was stretched to match but kept its chart at the top, so the two charts sat at different heights. A stretched tile now puts its chart at the bottom.
…in its tile A nine-digit count at large text is shrunk to fit its tile. The row sized its tiles before that shrinking, as if the figure had wrapped onto more lines, and left a gap between the figure and the chart. The figure now sits in a box one line tall, whatever it shrinks to.
…text Four figures across a 360 dp phone at large text touched each other and lost their labels. Where four do not fit, they now take two rows of two. A figure too wide for its column shrinks inside a box that stays one line tall, so the labels of all four stay level.
…its message A tap on Block or Unblock acts at once, on a list that re-reads itself every half minute and can reorder under a finger, and a block reaches everything that uses the server. The message that says what was done now offers Undo for eight seconds. It is not offered when the rule was already there: nothing changed, and the opposite tap would remove a rule this one never added.
An instance with no username or password gets the same 401 from a server that has a user as a wrong password does. The refused view told that person their password was not accepted and warned of a fifteen-minute block, when nothing had been sent that the server counts. It now says the server asks for a sign-in and where to add one.
Test connection on an instance with no username or password, against a server that has a user, said the sign-in was refused and warned of a fifteen-minute block. Nothing had been sent that the server counts. It now says the server asks for a sign-in, and tries both addresses, since there is nothing to hold back.
…e was entered With no username or password on the instance, the widget's refused state warned of a fifteen-minute block for wrong tries, though none had been made. It now says the server asks for a sign-in.
…Others, and a way to see all Each top list on the Home tab shows its first five rows, adds the rest up as Others, and opens the whole list on a screen of its own, where a domain can be blocked or unblocked as well. Response times are averages, so they are not added up. The message that says what a block or unblock did, with its Undo, is now shared by the tab and that screen.
…for queries and blocked DNS queries and Blocked by filters each get a card across the tab: the total with a second figure under it, and the series drawn large enough to read. For queries the second figure is the average processing time, for blocked it is the share of all queries. The other figures stay as small tiles. The average processing time moved into the queries card, and the tile it left shows the rules on the blocklists that are switched on.
A row's bar ran beside its figure, so a longer figure left a shorter bar and the bars of one list could not be read against each other. The bar now runs under the name and the figure both.
…3 Expressive indicator The rows used Flutter's stock bar. They now use the small flat form of the M3 Expressive one, with its gap and its dot at the end of the track.
…he first Both are drawn on one scale, so the second reads as its share of the first, as the blocked queries do of all of them.
Whole from ten percent up and with one decimal below that, for where the two decimals of the full figure do not fit.
…chart The widget was a pill, an icon and four plain figures. It now leads with the queries and the blocked ones as two large figures, shows the blocked share as a ring, and draws both over the period in a chart under them. The period and the rules on the blocklists sit in a line below. Pause is a button with its name on it instead of an icon, and Resume matches it.
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds AdGuard Home as a service, for #166. This is the first stage: the Home screen and a dashboard widget. Query log, filters, clients and settings are not built yet.
What it adds
Notes on the sign-in
AdGuard Home counts a wrong
Authorization: Basicheader sent to any path as a failed sign-in. After five of them (by default) it refuses that address for 15 minutes, and while it does the right password gets the same bare 401. So the module never repeats a refused sign-in by itself:Measured against a live server with a wrong password saved: one try for the connection test, one for the first read after saving, none while the screen stays open, one per Try again.
One known limit: the refusal is not remembered across app restarts, so each launch with a wrong saved password costs one try.
Testing
86 tests in
service_adguard_homeand 198 in the app. Verified on an emulator against AdGuard Home v0.107.79: the figures match the server, pause and resume reach it, and blocking a domain from a row writes the same custom rule the web UI does. The look was checked on a phone.Marked Beta.