This is the first step in rolling out the changes so that we can check via logging whether turning on the logic would reject anything it should not.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149050878
This fixes longstanding bug b/19430703 in which domain transfers that were
server-approved would only handle the autorenew grace period correctly if
the autorenew grace period was going to start within the transfer window.
If the autorenew grace period was already active (e.g. the domain had
recently autorenewed, before the transfer was requested), the logic would
miss it, even if it was going to be active throughout the transfer window
(i.e. it would still be active at the server-approval time).
When the autorenew grace period is active at the time a transfer is approved
(whether by the server or explicitly via DomainTransferApproveFlow), the
correct behavior is to essentially "cancel" the autorenew - the losing registrar
receives a refund for the autorenew charge, and the gaining registrar's transfer
extended registration years are applied to the expiration time as it was prior
to that autorenew. The way we implement this is that we just have the transfer
essentially "subsume" the autorenew - we deduct 1 year from the transfer's
extended registration years before extending the registration period from what
the expiration time is post-autorenew at the moment of transfer approval.
See b/19430703#comment17 for details on the policy justification; the only real
ICANN document about this is https://www.icann.org/news/advisory-2002-06-06-en,
but registrars informally document in many places that transfers will trigger
autorenew grace, e.g. see https://support.google.com/domains/answer/3251236
There are still a few parts of this bug that remain unfixed:
1) RdeDomainImportAction repeats a lot of logic when handling imported domains
that are in pending transfer, so it will also need to address this case in
some way, but the policy choices there are unclear so I'm waiting until we
know more about RDE import goals to figure out how to fix that.
2) Behavior at the millisecond edge cases is inconsistent - specifically, for
the case where a transfer is requested such that the automatic transfer
time is exactly the domain's expiration time (down to the millisecond),
the correct behavior is a little unclear and this CL for now ignores this
issue in favor of getting a fix for 99.999% of the issue into prod. See
newly created b/35881941 for the gory details.
Also, there are parts of this bug that will be fixed as parts of either
b/25084229 (transfer exDate computations) or b/35110537 (disallowing transfers
with extended registration years other than 1), both of which are less pressing.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149024269
This documents some slightly spooky behavior around domains that have an expiration time within their pendingDelete window (meaning the whole period from DomainDeleteFlow running to the actual deletionTime, not just the 5-day pendingDelete grace period). They will experience an autorenew in terms of expiration time and grace period status due to cloneProjectedAtTime(), but without the usual artifacts of an autorenew (billing event and poll message).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149019980
Currently, hasLogAtLevelWithMessage gave a very generic "no log at level with
message was found" error on failure. The user didn't know if there were no logs
at all, or if there was a small typo in the log etc.
Using the "regular" Truth assertions gives more informative errors in cleaner code.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149007204
This follows up on Brian's work to transition not just to a new format
with an empty scope value, but instead to replace the existing format
entirely with a new one that:
1) includes a version number to support future format migrations
2) doesn't include a field for the scope at all, since scoping the
tokens adds no real security benefit and just makes verification
more difficult
3) replaces the raw SHA-256 hash with a SHA-256 HMAC instead, as a
best practice to avoid length-extension attacks [1], even though
in our particular case they would only be able to extend the
timestamp and would thus be relatively innocuous
The new format will be produced by calling generateToken(), and the
scope-accepting version is renamed to generateLegacyToken() in addition
to its existing deprecation, for maximum clarity.
I changed the validateToken() logic to stop accepting a scope entirely;
when validating a legacy-style token, we'll test it against the two
existing legacy scope values ("admin" and "console") and accept it if
it matches either one.
Note that this means the xsrfScope parameter in @Action is now wholly
obsolete; I'll remove it in a follow-up to avoid bringing extra files
into this CL.
After this CL hits production, the next one will replace all calls to
generateLegacyToken() with generateToken(). Once that CL is deployed,
the last step will be removing the legacy fallback in validateToken().
[1] See https://en.wikipedia.org/wiki/Length_extension_attack
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148936805
I'm working on some changes to XsrfTokenManager (b/35388772) and ServerSecret
was crufty enough that I ended up rewriting it. Now it uses a LoadingCache
with a transaction instead of needlessly race-condition-y static init logic.
It also now supports retrieving its value as either a UUID (the old format
used by XsrfTokenManager) or a byte[]. The latter is more flexible and can
be directly used with HMAC which the new XsrfTokenManager format will employ.
And lastly, I added tests. In addition, I tested this code on alpha and
verified appropriate operation (XSRF tokens still work from the console and
from regtool; if you remove ServerSecret from datastore and memcache, it
persists a new one).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148931620
This adds a new method which will be used in an upcoming CL affecting domain
transfer logic. It also removes two older methods that are unused (they were
originally going to be used for TLD-specific logic which is now obsolete).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148928965
A few errors emerged when doing an integration test against the actual API. I've updated the unit tests to reflect the correct behavior.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148793856
This fixes an issue where RdeUploadActionTest relies on connecting to a local dummy SFTP server via the IPv4 loopback (127.0.0.1), which causes the test to fail on machines that only support IPv6. This updates the test to use just "localhost" instead.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148698178
Principally, this moves a load method into DatastoreHelper that is now
only used by tests.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148649087
It was kind of messy having all of that logic living alongside the
entities themselves.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148498024
This simplifies the tests for KmsKeyring and KmsUpdater.
This is a followup to []
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148496758
This also cleans up the PremiumList API so that it only has one
method for checking premium prices, which is by TLD, rather than two.
I will be refactoring a lot of the static methods currently residing in
the PremiumList class into a separate utils class, but I don't want to
include too many changes in this one CL.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148475345
This provides a safeguard against using TypeInstantiator to resolve the component class, where if resolution is done incorrectly, you end up with java.lang.Object. Formerly, that would have "succeeded" in generating a Router for Object, which of course has no methods that return @Action classes. Such a router is pretty useless, so it's better to make Router stricter and have it fail if you give it such a class by accident.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148353224
It turns out this type parameter was never necessary. A builder only needs the reflexive second type parameter when you want to have a builder inheritance hierarchy where the descendant builders have methods that the ancestor builder doesn't. In that case, the type param enables the ancestor builder's setter methods to automatically return the correct derived type, so that if you start with a derived builder, you can call a setter method inherited from an ancestor and then continue the chain with setters from the derived builder (e.g. new ContactResource.Builder().setCreationTime(now).setContactId(), which otherwise would have returned an EppResource.Builder from setCreationTime(), at which point the call to setContactId() would not compile).
Even then, it's not strictly necessary to use the type parameter, since you could instead just have each derived type override every inherited method to specify itself as the return type. But that would be a lot of extra boilerplate and brittleness.
Anyway, in this case, there is a builder hierarchy, but RequestComponentBuilder specifies all the methods that we're ever going to want on our builders, so there's never any need to be able to call specific derived builder methods. We only even need the individual builder classes so that Dagger can generate them separately for each component.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148269178
This fixes a bug in the interaction between ListObjectsAction and ListObjectsCommand/AppEngineConnection. ListObjectsAction was returning HTTP status code 400 when it caught an IAE, but also attempting to return a JSON response payload of {"status": "error", "error": "<exception message>"}. However, AppEngineConnection treats any HTTP error response as more like a crash on the server side - it attempts to scrape the error message out of the autogenerated HTML that AppEngine produces for uncaught exceptions, and throws an exception, killing ListObjectsCommand before it can extract the JSON which contains the nicer error (that stating the missing field, etc versus just "400 Bad Request").
The fix is just to have ListObjectsAction return a 200 and the error message so that ListObjectsCommand can correctly handle it.
I also de-scoped the catch to only catching IAE, since catching Exception was overbroad, and the only "expected" exception to be thrown is an IAE from the checkArgument() that tests if the requested fields all exist. Any other kinds of exceptions should actually just bubble up and kill the action, and get the regular AppEngineConnection error treatment.
I also added "billingId" as an alias for "billingIdentifier", parallel to clientId/clientIdentifier, since that's why I came across this issue in the first place.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148248834
Remove line that loads RegistryConfigSettings from RegistryConfigTest.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148236844
Store the auth credentials under a name qualified by the set of OAuth scopes
as well as the client id. This is implemented as the base64 encoded SHA1 hash
of the concatenation of client id and sorted auth scopes.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148127911
Seems silly that one command uses --tlds for the required parameter, while the other one doesn't.
As part of this change, create a DateParameter for commands that require only a date (i.e. a DateTime parameter restricted to midnight UTC).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148106721
The one-day validity period is also moved from the caller into XsrfTokenManager.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=147857716
No actual injection is happening in test, and at least some compilers complain that @Inject qualifiers are not allowed on non-static inner classes.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=147835985
Implement client-side OAuth in non-local HTTP connections. Also add tests to
verify that the different modes of connection are set up correctly.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=147636222
This is the first step in the migration to remove the need to load all of
the premium list entries every time the cache expires (which causes slow-
downs). Once this is deployed, we can re-save all premium lists, creating
the bloom filters, and then the next step will be to read from them to
more efficiently determine if a label might be premium.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=147525017
This was an oversight I noticed ages ago, so resurrecting some old local changes I had to correct it.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=146812322
All domain/host names should be stored in their canonical forms (puny-
coded and lower-cased). This validation is already in the flows, but
this adds protection against bad data from other sources, e.g. admin
consoles or RDE imports.
This also removes an old work-around that temporarily suspended this
validation for superusers, because we used to have non-canonicalized
data in the system. The non-canonicalized data has since all been
cleaned up, so this work-around is no longer necessary.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=146799558