Repository: internetarchive/openlibrary

Issue:
Attempting to link an existing account silently fails
### Evidence / Screenshot (if possible)

<img width="948" alt="Screenshot 2024-01-04 at 19 37 33" src="https://github.com/internetarchive/openlibrary/assets/2069958/89b0c68c-6890-4737-a98b-49ee8b4426d2">

<img width="870" alt="Screenshot 2024-01-04 at 19 37 57" src="https://github.com/internetarchive/openlibrary/assets/2069958/8375ad11-d03f-4342-9026-e923307aae76">

### Relevant url?
https://openlibrary.org/account/login

### Steps to Reproduce
1. Sign up to Internet Archive with the "Sign in with Google" option
2. Log into Open Library
3. Delete Internet Archive account
4. Create a new Internet Archive account with the same email address
5. Log into Open Library with the "Sign in with Google" option
6. Click the "Link accounts" button

* Actual: The linking silently fails
* Expected: To be able to relink my existing Open Library account with the new Internet Archive account




Discussion:
Hey @codeinabox thanks for raising this issue, i think this is probably because the system might retain some data related to the previous association between the Open Library account and the old Internet Archive account, causing a conflict when attempting to re-link with a new Internet Archive account using the same email or it might be because of authentication tokens or session data associated with the previous account that interferes with the linking process. 

That being said i think this sure needs some more discussion.
> Hey @codeinabox thanks for raising this issue, i think this is probably because the system might retain some data related to the previous association between the Open Library account and the old Internet Archive account, causing a conflict when attempting to re-link with a new Internet Archive account using the same email or it might be because of authentication tokens or session data associated with the previous account that interferes with the linking process.
> 
> That being said i think this sure needs some more discussion.

Not a problem, I am personally affected by this bug as I can't log into Open Library any more. I took a screenshot when trying to relink my account, so can provide details of when this error occurred and my email.
@iisa have we hit similar cases here on archive.org re: oauth?
If this still needs someone to work on it, I'd be happy to put some time into it! Could you assign me? 
@benbdeitch this may be a tough one to debug. I think what is happening is:

When one creates or links an Open Library account to an existing archive.org account, the `itemidentifier` of form `@archiveusername` gets written to the Open Library `web.ctx.store` db table in the patron's json object.

If the archive.org account is deleted but the `itemidentifier` field persists on the patron's store object, this might cause problems. If the `itemidentifier` (could be spelled differently) in the store table is invalid or doesn't exist on Archive.org, we should remove / nullify this field from the `store` object and retry whatever function attempts to link to archive.org

One problem is, typically we create and activate an Archive.org account behind the scenes _before_ creating an Open Library account... In `accounts/models.py` within `audit` there should be logic which handles this case, fetches the Open Library account, and then attempts to register an archive.org account + send an activation email + then link existing OL to IA on activation success + 1st login
Wonderful! I'll try to get started on it very soon; I accidentally overcommitted slightly, so it might be another day or two before I can properly get to this.  

Out of curiousity, is the goal for this pull request to fix the issue, have the 'silent' issue notify the user, or both? 
If there's a bug, we want to fix it. In the cases where a bug is encountered and there is no fix (e.g. archive.org is down while an OL patron is registering) then we want to notify the patron correctly 
Right, sorry that it took me so long to get to this; I'll be working on it as of tomorrow. 
After chipping away at this, I don't think I'll be able to resolve this issue.  Figuring out where the error is occurring feels like it will necessitate knowledge of how Internet Archive authenticates its users, and the relevant gitlab is restricted to staff only.   

Still, it was a pleasure to try my hand at, and I think I've learned a lot about infogami in the process. Good luck to the next person to take it on! 

Resolving patch:
diff --git a/openlibrary/accounts/model.py b/openlibrary/accounts/model.py
--- a/openlibrary/accounts/model.py
+++ b/openlibrary/accounts/model.py
@@ -825,11 +825,17 @@ def audit_accounts(
         ol_account = OpenLibraryAccount.get(link=ia_account.itemname, test=test)
         link = ol_account.itemname if ol_account else None
 
-        # The fact that there is no link implies no Open Library account exists
-        # containing a link to this Internet Archive account...
+        # The fact that there is no link implies either:
+        # 1. There was no Open Library account ever linked to this IA account
+        # 2. There is an OL account, and it was linked to this IA account at some point,
+        #    but the linkage was broken at some point.
+
+        # Today, it is possible for #2 to occur if a patron creates an IA account, deletes said
+        # account, then creates a new IA account using the same email that was used to create the
+        # original account.
         if not link:
-            # then check if there's an Open Library account which shares
-            # the same email as this IA account.
+            # If no account linkage is found, then check if there's an Open Library account
+            # which shares the same email as this IA account.
             ol_account = OpenLibraryAccount.get(email=email, test=test)
 
             # If an Open Library account with a matching email account exists...
@@ -838,7 +844,15 @@ def audit_accounts(
             # Open Library account having the same email as our IA account must have
             # been linked to a different Internet Archive account.
             if ol_account and ol_account.itemname:
-                return {'error': 'wrong_ia_account'}
+                logger.error(
+                    'IA <-> OL itemname mismatch',
+                    extra={
+                        'ol_itemname': ol_account.itemname,
+                        'ia_itemname': ia_account.itemname,
+                    },
+                )
+                ol_account.unlink()
+                ol_account.link(ia_account.itemname)
 
         # At this point, it must either be the case that
         # (a) `ol_account` already links to our IA account (in which case `link` has a


Test patch: