Skip to content

Add Django OAuth login with Pywikibot integration - #135

Open
sergyDwhiz wants to merge 18 commits into
Wikimedia-Suomi:mainfrom
sergyDwhiz:feature/117-oauth-login
Open

Add Django OAuth login with Pywikibot integration#135
sergyDwhiz wants to merge 18 commits into
Wikimedia-Suomi:mainfrom
sergyDwhiz:feature/117-oauth-login

Conversation

@sergyDwhiz

@sergyDwhiz sergyDwhiz commented Oct 29, 2025

Copy link
Copy Markdown
Contributor

This pull request integrates Django Social Auth with the MediaWiki OAuth 1.0a backend, enabling users to authenticate using their Wikimedia accounts.

Changes made include:

  • Integrated and configured social-auth-app-django with the MediaWiki backend.
  • Added a “Login with Wikimedia” button to the top-right navigation bar (visible only when OAuth is enabled).
  • Implemented a robust logout flow that fully clears user sessions.
  • Introduced a helper function which retrieves OAuth tokens from Django Social Auth and supplies them to Pywikibot for authenticated bot operations.
  • Added an OAUTH_ENABLED environment variable for backward compatibility — when disabled, the application retains its previous authentication behavior.
  • Updated all relevant settings, URLs, views, and templates to support the new authentication flow.
  • Included a comprehensive testing guide to facilitate validation of the integration.

Addresses: #117

- Add Django Social Auth with MediaWiki OAuth 1.0a backend
- Configure OAuth callback URL with trailing slash
- Add login/logout views and URL routes
- Update UI with login button in top right corner
- Implement configure_pywikibot_oauth() helper function
@sergyDwhiz

Copy link
Copy Markdown
Contributor Author

Hi @zache-fi,

The OAuth implementation is complete and tests pass, but I'm hitting 403 Forbidden errors when testing the full OAuth flow from localhost (even after registering OAuth consumers with proper callback URLs on meta.wikimedia.org).

How do you typically test OAuth locally for this project? Should I use ngrok for a public URL, test on a deployed environment, or is there another approach you recommend?

The code looks correct based on Django Social Auth docs, but I can't verify the end-to-end flow due to this localhost limitation. Everything is documented in the OAUTH_TESTING_GUIDE.md.
Please let me know your advice, Thanks.

@zache-fi

zache-fi commented Oct 29, 2025

Copy link
Copy Markdown
Contributor

Hi, try to register it at meta.wikimedia.beta.wmflabs.org/ and use it as endpoint. It doesn't work for superset, but I can approve ouths there so registering and finding correct value can be done trial and error.

@zache-fi

Copy link
Copy Markdown
Contributor

Just FYI. I can test the correct values.

@zache-fi

Copy link
Copy Markdown
Contributor

Note https://meta.wikimedia.beta.wmcloud.org doesn't use wikimedias unified login so you need to register separate account there.

Oauth consumer registration
So I used these values when i registered the Oauth consumer in https://meta.wikimedia.beta.wmcloud.org/wiki/Special:OAuthConsumerRegistration/propose

  • Application name: PendingChangesBot test 2
  • Consumer version: 1.0
  • Application description: PendingChangesBot is FlaggedRevs automatic review bot ( https://github.com/Wikimedia- Suomi/PendingChangesBot-ng )
  • This consumer is for use only by Zache-test: NOT SELECTED
  • OAuth "callback" URL: http://127.0.0.1:8000/
  • Allow consumer to specify a callback in requests and use "callback" URL above as a required prefix.: SELECTED
  • Contact email address: MY EMAIL ADDRESS
  • Applicable project: *
  • Types of grants being requested: Request authorization for specific permissions.
  • Applicable grants:
    • Edit existing pages
    • Create, edit, and move pages
    • Patrol changes to pages
    • Rollback changes to pages

settings.py

# MediaWiki OAuth 1.0a settings
# For development: use meta.wikimedia.org (beta is often blocked)
# For production: use meta.wikimedia.org
SOCIAL_AUTH_MEDIAWIKI_URL = "https://meta.wikimedia.beta.wmcloud.org/w/index.php"
SOCIAL_AUTH_MEDIAWIKI_KEY = "CONSUMER_TOKEN_FROM_OAUTH_REGISTRATION"
SOCIAL_AUTH_MEDIAWIKI_SECRET = "SECRET_TOKEN_FROM_OAUTH_REGISTRATION"
SOCIAL_AUTH_MEDIAWIKI_CALLBACK = "http://127.0.0.1:8000/oauth/complete/mediawiki/"

@zache-fi

Copy link
Copy Markdown
Contributor

Btw is beta blocked for you?

- Keep social-auth-app-django for OAuth
- Keep upstream type checking and security tools
- Changed default SOCIAL_AUTH_MEDIAWIKI_URL to meta.wikimedia.beta.wmcloud.org
- Updated OAUTH_TESTING_GUIDE.md with Zache's specific registration instructions
@ademolaomosanya ademolaomosanya added the ready for review Indicates the PR is complete and ready for maintainer review. label Oct 29, 2025
@zache-fi

zache-fi commented Oct 31, 2025

Copy link
Copy Markdown
Contributor

Yes, the login works now. There could be still couple of changes.

Fix the ruff check

Add to the top of the page navigation bar (similarly than in https://wikikysely-dev.toolforge.org/en/ ) and move the login button to top right of the bar. This just to make it look nicer.

Another change would be that save the actual Wikimedia Commons username . (Reusing Djangos first_name field would be OK as we arent using it anywhere and would not require any user model customization ) This is because Django will "normalize" usernames (ie removes high-bit characters for example) before saving it to username field so it cannot be used for showing the username.

Try if you can pass the Oauth credidentials to pywikibot instance after you have logged in. If Oauth endpoint used for login is https://meta.wikimedia.beta.wmcloud.org then use commons beta also in code.

  pywikibot.config.usernames['commons']['beta']= user.username
  site = pywikibot.Site('beta', 'commons')

If you have logged in using https://meta.wikimedia.org then both values are "commons"

pywikibot.config.usernames['commons']['commons']= user.username
site = pywikibot.Site('commons', 'commons')

Here is example code

Note you need login commons once so it will create a user to target wiki before this work.

- Add top navigation bar with login button in top-right corner
- Save original Wikimedia username in first_name field (avoid normalization)
- Update Pywikibot OAuth config to use beta/production appropriately
- Configure pywikibot.config.usernames based on OAuth endpoint
- Display first_name (original username) in navbar if available
- Fix ruff formatting issues
@sergyDwhiz

Copy link
Copy Markdown
Contributor Author

Hi @zache-fi! Thanks for the feedback!
I've implemented all four changes you requested: ruff checks, a top navigation bar with login in the top-right and configured Pywikibot OAuth to auto-detect beta vs production environments based on the OAuth URL.

Please let me know next steps.

Copilot AI review requested due to automatic review settings November 1, 2025 02:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@zache-fi

zache-fi commented Nov 1, 2025

Copy link
Copy Markdown
Contributor

check why the test is failing and fix it

@sergyDwhiz

Copy link
Copy Markdown
Contributor Author

Thanks for catching that. I think it's a template syntax issue with Vue. Let me take a more keen look. Thanks

- Replace Vue.js syntax with v-text directive to avoid Django parser conflicts
- Remove verbatim tags as they're no longer needed with v-text
@xenacode-art

xenacode-art commented Nov 3, 2025

Copy link
Copy Markdown
Contributor

Hi @sergyDwhiz! 👋

Excellent work on the OAuth integration! I've reviewed the code and tested it locally. This is a crucial
piece of infrastructure for the internship roadmap. Here's my detailed feedback:

✅ What Works Well

Architecture:

  • Clean separation of OAuth logic using Django Social Auth
  • Smart handling of beta vs production endpoints
  • Backwards compatibility with OAUTH_ENABLED flag is great for gradual rollout

Pywikibot Integration:

  • The get_pywikibot_site_with_oauth() helper function is elegant
  • Automatically configuring Pywikibot from Django session tokens avoids credential duplication
  • Good error handling when OAuth tokens aren't available

UI/UX:

  • Login button placement in navigation makes sense
  • Preserving original Wikimedia usernames in first_name is clever workaround for Django's normalization

Testing & Observations

I tested this locally with the following scenarios:

Scenario 1: OAuth Login Flow

  • Login button appears when not authenticated
  • Redirects to Wikimedia OAuth authorization
  • Successfully returns and creates Django session
  • Username displays correctly in navbar

Scenario 2: OAuth Disabled Mode

  • Application works with OAUTH_ENABLED=False
  • Previous authentication methods still function
  • No errors in logs

Scenario 3: Pywikibot Integration

  • OAuth tokens passed correctly to Pywikibot
  • Bot operations work with OAuth credentials
  • ⚠️ Need to verify with actual flaggedrevs operations (requires wiki with FlaggedRevs enabled)

Minor Suggestions

1. Error Messaging:
When OAuth login fails, users see a generic error. Consider adding user-friendly error messages:

# In views or middleware
except SocialAuthException as e:
    messages.error(request, "OAuth login failed. Please try again or contact support.")

2. Session Timeout:
Consider documenting the session timeout behavior. Users should know how long they stay logged in.

3. Testing Documentation:
It would be helpful to add a section in the README about:
- How to set up beta OAuth consumer for testing
- Environment variables needed
- Common troubleshooting steps


Great foundational work! 🚀




## If you need assistance with:
- Writing additional tests for edge cases
- Resolving any test failures
- Adding documentation
- Testing with production-like scenarios

I'm happy to collaborate! We could pair on this to get it across the finish line.

@sergyDwhiz

Copy link
Copy Markdown
Contributor Author

Hi @xenacode-art, sorry for my late reply. I've been through a lot.

Thanks so much for the thorough review and testing. I appreciate you taking the time to verify everything works! Your suggestions about error messaging, session timeout documentation and testing are true. I've been working on a fix for the template syntax conflicts that came back after the merge. Pushing it soon.
Thanks.

@xenacode-art

Copy link
Copy Markdown
Contributor

@sergyDwhiz glad to have you back hope you're doing okay.

@sergyDwhiz

Copy link
Copy Markdown
Contributor Author

Thanks bro, and I'm good. Hope same?

@sergyDwhiz

Copy link
Copy Markdown
Contributor Author

We need to do everything to close this PR sooner bro. It's a crucial feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Indicates the PR is complete and ready for maintainer review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants