Class AdminLoginLocation
The login flow has a pre-login lookup and one fallback after authentication:
- The login page runs
/admin/scripts/login-location.js, which calls the external IP lookup URL fromgetLookupUrl()directly from the browser. It posts only the city and country code to/admin/logon/location/, whereAdminLoginLocationControllerdelegates toprepare(HttpSession, Input). - The validated hint is stored under
PENDING, with its receipt time.LogonToolsexplicitly copies it when replacing the HTTP session, so it remains available through additional authentication steps. - After authentication succeeds,
LogonTools.afterSuccessLogoncallsbeginLogin(HttpSession). It consumes the hint if it is at most ten minutes old and exposes it throughgetLocation(HttpSession)beforeAdminDeviceServicerecords the device login and sends any new-device notification.SessionHolderalso reads this location when updating session details. - If the location is still missing,
LayoutServicecallstakeRetryUrl(HttpSession)for the first rendered administration page, including direct editor links. The same script retries the lookup and posts to/admin/rest/security/login-location. The controller updates the current session and cluster summary throughsetLocation(HttpSession, String). It also asksDeviceServiceto fill the device's missing location only if its latest login still matchesDEVICE_LOGIN_TIME; this fallback does not resend the email.
Lookup failures do not delay or prevent authentication. The location is untrusted display metadata, never evidence for authentication or device ownership. The browser supplies no account, device or session identifiers; the controller derives the target from the caller's session.
The adminLoginLocationApiKey setting selects the provider: an empty value uses
ipwho.is, a key uses ipwhois.pro, and DISABLED turns lookup off.
A configured key is intentionally included in the URL sent to the browser.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordContains the untrusted location fields submitted by the browser, without target identifiers. -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionstatic voidbeginLogin(jakarta.servlet.http.HttpSession session) Starts a successful administrator login by consuming its pending location hint once.static StringgetLocation(jakarta.servlet.http.HttpSession session) static StringBuilds the external IP lookup URL for the browser without making a server-side request.static booleanstatic voidprepare(jakarta.servlet.http.HttpSession session, AdminLoginLocation.Input input) Validates a pre-login hint and stages it in the session with the current server time.static voidsetLocation(jakarta.servlet.http.HttpSession session, String location) Applies a location to the HTTP session and any existing session details after a fallback lookup.static StringtakeRetryUrl(jakarta.servlet.http.HttpSession session) Reserves one browser lookup retry when rendering an administration page without a location.static Stringvalidate(AdminLoginLocation.Input input) Validates and normalizes browser input into display text such asBratislava, SK.
-
Field Details
-
PENDING
- See Also:
-
DEVICE_LOGIN_TIME
- See Also:
-
-
Method Details
-
isEnabled
public static boolean isEnabled() -
getLookupUrl
Builds the external IP lookup URL for the browser without making a server-side request.An empty API key selects the free endpoint; otherwise the URL includes the encoded paid key, which is visible to the browser. Only success, city and country code are requested.
- Returns:
- lookup URL, or
nullwhen the configuration isDISABLED
-
prepare
public static void prepare(jakarta.servlet.http.HttpSession session, AdminLoginLocation.Input input) Validates a pre-login hint and stages it in the session with the current server time.The controller calls this for an unauthenticated session. A valid hint replaces any pending hint; disabled lookup or invalid input leaves the session unchanged. The hint becomes the login location only when
beginLogin(HttpSession)consumes it.- Parameters:
session- non-null pre-login session to hold the pending hintinput- browser-supplied city and country code;nullor invalid input is ignored
-
beginLogin
public static void beginLogin(jakarta.servlet.http.HttpSession session) Starts a successful administrator login by consuming its pending location hint once.Called after all required authentication steps and before device recording and notification. The pending hint is removed regardless of validity. It becomes the current location only if lookup is enabled and it is at most ten minutes old; otherwise any previous location is cleared. The retry marker and device login timestamp are also cleared for the new login.
- Parameters:
session- non-null authenticated session containing any preserved pre-login hint
-
getLocation
-
takeRetryUrl
Reserves one browser lookup retry when rendering an administration page without a location.The reservation is recorded before returning the URL, so later page renders do not retry even if the browser lookup fails.
beginLogin(HttpSession)resets this marker for the next successful login.- Parameters:
session- current administrator session, ornullwhen no session exists- Returns:
- lookup URL for the reserved attempt, or
nullif the session is absent, lookup is disabled, a location is already present or a retry was already reserved
-
validate
Validates and normalizes browser input into display text such asBratislava, SK.The trimmed city must contain 1 to 156 characters and no ISO control characters. The trimmed, uppercased country code must contain exactly two ASCII letters. These checks bound the input but do not verify the location or escape HTML; callers must render it as text.
- Parameters:
input- untrusted city and country code; may benull- Returns:
- normalized
city, CCtext, ornullif either field is missing or invalid
-
setLocation
Applies a location to the HTTP session and any existing session details after a fallback lookup.If session details exist, their location is updated and administrator details trigger a cluster summary update. This method does not validate input or update the persisted device; the controller handles validation and delegates the device update to
DeviceService.- Parameters:
session- non-null session whose location is being updatedlocation- validated display text, ornullto clear the location
-