You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ponymail.apache.org by hu...@apache.org on 2025/12/16 16:15:04 UTC

(incubator-ponymail-foal) branch master updated (8637f08 -> 6660b94)

This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git


    from 8637f08  Reduce noise
     new 5a708d2  Centralise oauth configuration
     new cf09c90  Bump versions
     new 1ff93b3  Private repo nees private lists
     new a1b4bd7  Default to empty string, saving re.match from breaking
     new 0f78e6a  Bump version
     new fca3121  Run version tests last
     new 44326c0  Check for invalid provider key - just in case
     new 328bbcd  Update server version
     new 6660b94  Merge remote-tracking branch 'ponymail-foal/oauth-simplify'

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/integration-tests.yml |  6 ++++
 server/endpoints/oauth.py               |  3 +-
 server/endpoints/preferences.py         |  6 ++++
 server/plugins/configuration.py         |  2 ++
 server/plugins/oauthGeneric.py          | 13 ++++---
 server/ponymail.yaml.example            | 61 +++++++++++++++++++++++++--------
 server/testendpoints/testauth.py        | 30 ++++++++--------
 test/itest_integration.py               | 13 +++++--
 webui/js/config.js                      | 36 -------------------
 webui/js/oauth.js                       | 24 ++++++++++---
 webui/oauth.html                        |  2 +-
 11 files changed, 114 insertions(+), 82 deletions(-)


(incubator-ponymail-foal) 08/09: Update server version

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit 328bbcdc590692fa61299096e326da5a36522541
Author: Sebb <se...@apache.org>
AuthorDate: Tue Oct 21 15:58:36 2025 +0100

    Update server version
---
 server/server_version.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/server_version.py b/server/server_version.py
index b032e44..ddc315a 100644
--- a/server/server_version.py
+++ b/server/server_version.py
@@ -1,2 +1,2 @@
 # This file is generated by server/update_version.sh
-PONYMAIL_SERVER_VERSION = 'a1b4bd7'
+PONYMAIL_SERVER_VERSION = '44326c0'


(incubator-ponymail-foal) 03/09: Private repo nees private lists

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit 1ff93b343b8d41c10f3602fed857400b8eeb06e5
Author: Sebb <se...@apache.org>
AuthorDate: Thu Jul 25 00:25:12 2024 +0100

    Private repo nees private lists
---
 .asf.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.asf.yaml b/.asf.yaml
index 27bd8d6..705b2d6 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -21,5 +21,5 @@ github:
     issues: true
 
 notifications:
-    issues:       issues@ponymail.apache.org
-    jobs:         dev@ponymail.apache.org
+    issues:       private@ponymail.apache.org
+    jobs:         private@ponymail.apache.org


(incubator-ponymail-foal) 01/09: Centralise oauth configuration

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit 5a708d2493b2e738dda31308f1db8e9a4d3872d5
Author: Sebb <se...@apache.org>
AuthorDate: Thu Jul 25 00:10:27 2024 +0100

    Centralise oauth configuration
---
 .github/workflows/integration-tests.yml |  6 ++++
 server/endpoints/oauth.py               |  3 +-
 server/endpoints/preferences.py         |  6 ++++
 server/plugins/configuration.py         |  2 ++
 server/plugins/oauthGeneric.py          | 10 +++---
 server/ponymail.yaml.example            | 61 +++++++++++++++++++++++++--------
 server/server_version.py                |  2 +-
 server/testendpoints/testauth.py        | 30 ++++++++--------
 test/itest_integration.py               | 13 +++++--
 webui/admin.html                        |  8 ++---
 webui/index.html                        |  6 ++--
 webui/js/config.js                      | 36 -------------------
 webui/js/oauth.js                       | 24 ++++++++++---
 webui/js/ponymail.js                    |  2 +-
 webui/list.html                         |  8 ++---
 webui/oauth.html                        | 10 +++---
 webui/thread.html                       |  8 ++---
 17 files changed, 132 insertions(+), 103 deletions(-)

diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
index 01a160d..c5b28b3 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -78,6 +78,12 @@ jobs:
             - localhost
           admins:
             - admin@apache.org
+          providers:
+            testprovider:
+              name:           Test Auth User
+              oauth_portal:   http://localhost:8080/api/testauth
+              .oauth_url:     http://localhost:8080/api/testauth
+
         
         EOD
         echo server/ponymail.yaml 
diff --git a/server/endpoints/oauth.py b/server/endpoints/oauth.py
index ddf231f..3bf08d3 100644
--- a/server/endpoints/oauth.py
+++ b/server/endpoints/oauth.py
@@ -39,7 +39,6 @@ async def process(
     state = indata.get("state")
     code = indata.get("code")
     id_token = indata.get("id_token")
-    oauth_token = indata.get("oauth_token")
 
     rv: typing.Optional[dict] = None
 
@@ -52,7 +51,7 @@ async def process(
         rv = await plugins.oauthGithub.process(indata, session, server)
 
     # Generic OAuth handler, only one we support for now. Works with ASF OAuth.
-    elif state and code and oauth_token:
+    elif state and code:
         rv = await plugins.oauthGeneric.process(indata, session, server)
 
     if rv:
diff --git a/server/endpoints/preferences.py b/server/endpoints/preferences.py
index af9b3af..12965ea 100644
--- a/server/endpoints/preferences.py
+++ b/server/endpoints/preferences.py
@@ -43,6 +43,12 @@ async def process(
 
     prefs: dict = {"login": {}}
     prefs['versions'] = versions
+    if indata.get('oauth'):
+        # filter subkeys starting with .
+        # the providers is a dict of dicts; we want to filter out keys in the inner dict that start with '.'
+        prefs['oauth'] = { provider:{ k:v for k,v in entry.items() if not k.startswith('.')} 
+                  for provider,entry in server.config.oauth.providers.items()}
+        return prefs
     lists: dict = {}
     for ml, entry in server.data.lists.items():
         if "@" in ml:
diff --git a/server/plugins/configuration.py b/server/plugins/configuration.py
index 7701c0e..6418a81 100644
--- a/server/plugins/configuration.py
+++ b/server/plugins/configuration.py
@@ -63,6 +63,7 @@ class OAuthConfig:
     google_client_id: str
     github_client_id: str
     github_client_secret: str
+    providers: dict # generic providers
 
     def __init__(self, subyaml: dict):
         self.authoritative_domains = subyaml.get("authoritative_domains", [])
@@ -70,6 +71,7 @@ class OAuthConfig:
         self.google_client_id = subyaml.get("google_client_id", "")
         self.github_client_id = subyaml.get("github_client_id", "")
         self.github_client_secret = subyaml.get("github_client_secret", "")
+        self.providers = subyaml.get("providers", {})
 
 
 class DBConfig:
diff --git a/server/plugins/oauthGeneric.py b/server/plugins/oauthGeneric.py
index 8264370..14818b8 100644
--- a/server/plugins/oauthGeneric.py
+++ b/server/plugins/oauthGeneric.py
@@ -23,16 +23,18 @@ import typing
 import aiohttp.client
 
 
-async def process(formdata: dict, _session, _server) -> typing.Optional[dict]:
+async def process(formdata: dict, _session, server) -> typing.Optional[dict]:
+    provider = formdata["key"]
+    oauth_url = server.config.oauth.providers.get(provider).get('.oauth_url')
     # Extract domain, allowing for :port
     # Does not handle user/password prefix etc
-    m = re.match(r"https?://([^/:]+)(?::\d+)?/", formdata["oauth_token"])
+    m = re.match(r"https?://([^/:]+)(?::\d+)?/", oauth_url)
     if m:
         oauth_domain = m.group(1)
         headers = {"User-Agent": "Pony Mail OAuth Agent/0.1"}
         # This is a synchronous process, so we offload it to an async runner in order to let the main loop continue.
-        async with aiohttp.client.request("POST", formdata["oauth_token"], headers=headers, data=formdata) as rv:
+        async with aiohttp.client.request("POST", oauth_url, headers=headers, data=formdata) as rv:
             js = await rv.json()
             js["oauth_domain"] = oauth_domain
         return js
-    return None
\ No newline at end of file
+    return None
diff --git a/server/ponymail.yaml.example b/server/ponymail.yaml.example
index a9d27e3..0fd0571 100644
--- a/server/ponymail.yaml.example
+++ b/server/ponymail.yaml.example
@@ -1,3 +1,4 @@
+
 server:
   port: 8080             # Port to bind to
   bind: 127.0.0.1        # IP to bind to - typically 127.0.0.1 for localhost or 0.0.0.0 for all IPs
@@ -6,7 +7,7 @@ server:
 database:
   dburl:     http://localhost:9200/   # The URL of the ElasticSearch database
   db_prefix: ponymail                 # DB prefix, usually 'ponymail'
-  max_hits: 15000                     # Maximum number of emails to process in a search
+  max_hits:  15000                    # Maximum number of emails to process in a search
   pool_size: 15                       # number of connections for async queries
   max_lists: 8192                     # max number of lists to allow for
 
@@ -23,17 +24,47 @@ ui:
 
 # Fill in OAuth data as needed
 oauth:
-# If using OAuth, set the authoritative domains here. These are the OAuth domains that 
-# will provide access to private emails.
-# N.B. This must be defined as an array (or omitted)
-# authoritative_domains:
-#   - localhost        # for local testing of sending email
-#    - googleapis.com  # OAuth via google is authoritative
-#    - github.com      # GitHub OAuth is authoritative
-# Set up users with administrative permission
-# N.B. This must be defined as an array (or omitted)
-# admins:
-#    - localtest@apache.org
-#  google_client_id:     ~
-#  github_client_id:     ~
-#  github_client_secret: ~
+  # Details of providers to be shown by the front end
+  # Note that there should be a corresponding icon at images/ouath_<key>.png
+  providers:
+    apache:
+      name:           Apache OAuth
+      oauth_portal:   https://oauth.apache.org/
+      .oauth_url:     https://oauth.apache.org/token
+      fullname_key:   fullname # does not appear to be used
+      email_key:      email
+    google:
+        name:         Google OAuth
+        oauth_portal: https://accounts.google.com/o/oauth2/auth
+        fullname_key: name # does not appear to be used
+        email_key:    email
+        client_id:    41983040784-s1gl269f0p537r22h8eai2pdr1a94pfg.apps.googleusercontent.com
+    github:
+        name:         GitHub OAuth
+        oauth_portal: https://github.com/login/oauth/authorize
+        client_id:    your-client-id-here
+        scope:        user:email
+        construct:    true # encode all the above keys
+    # Enable these for testing purposes (see testauth.py)
+    # user:
+    #   name:           Test Auth User
+    #   oauth_portal:   http://localhost:1080/api/testauth
+    #   .oauth_url:     http://localhost/api/testauth
+    # admin:
+    #   name:           Test Auth Admin
+    #   oauth_portal:   http://localhost:1080/api/testauth
+    #   .oauth_url:     http://localhost/api/testauth
+  # If using OAuth, set the authoritative domains here. These are the OAuth domains that
+  # will provide access to private emails.
+  # N.B. This must be defined as an array (or omitted)
+  # authoritative_domains:
+  #   - localhost        # for local testing of sending email
+  #    - googleapis.com  # OAuth via google is authoritative
+  #    - github.com      # GitHub OAuth is authoritative
+  # Set up users with administrative permission
+  # N.B. This must be defined as an array (or omitted)
+  # admins:
+  #    - localtest@apache.org
+  #  google_client_id:     ~
+  #  github_client_id:     ~
+  #  github_client_secret: ~
diff --git a/server/server_version.py b/server/server_version.py
index aa9ce5e..f49c017 100644
--- a/server/server_version.py
+++ b/server/server_version.py
@@ -1,2 +1,2 @@
 # This file is generated by server/update_version.sh
-PONYMAIL_SERVER_VERSION = '866bae5'
+PONYMAIL_SERVER_VERSION = '3416ada'
diff --git a/server/testendpoints/testauth.py b/server/testendpoints/testauth.py
index 9d2d0f0..7e7033e 100644
--- a/server/testendpoints/testauth.py
+++ b/server/testendpoints/testauth.py
@@ -22,32 +22,30 @@ To enable:
 - ensure server/ponymail.yaml contains the following in the oauth section:
 
 oauth:
+  providers:
+  ...
+    user:
+      name:           Test Auth User
+      oauth_portal:   http://localhost:1080/api/testauth
+      .oauth_url:     http://localhost/api/testauth
+    admin:
+      name:           Test Auth Admin
+      oauth_portal:   http://localhost:1080/api/testauth
+      .oauth_url:     http://localhost/api/testauth
   ...
   authoritative_domains:
     - localhost
   admins:
     - admin@apache.org
 
+(This assumes that the test installation is at http://localhost/. Adjust as necessary.)
+Note: if using a Docker container with a different host port, adjust the oauth_portal entries only
+
 - Add the --testendpoints qualifier to the server startup command
   Alternatively copy the files server/test/testauth.[py|.yaml] to the server/endpoints directory
   They can be renamed if necessary, so long as they have the same basename;
   adjust the URLs below to reflect the new name
 
-- then add the following to config.js under pm_config.oauth:
-        user: {
-            name: "Test Auth User",
-            oauth_portal: "http://localhost/api/testauth",
-            oauth_url: "http://localhost/api/testauth"
-        },
-        admin: {
-            name: "Test Auth Admin",
-            oauth_portal: "http://localhost/api/testauth",
-            oauth_url: "http://localhost/api/testauth"
-        },
-(This assumes that the test installation is at http://localhost/. Adjust as necessary.)
-Note: if using a Docker container with a different host port, adjust the oauth_portal entries only
-(the oauth_url entries relate to the port used by the container webserver)
-
 This will add two extra options to the login screen.
 Clicking on either "Test sign in as ..." link will automatically login (without prompting)
 
@@ -62,7 +60,7 @@ import yaml
 
 def debug(server, text):
     if server.api_logger:
-        server.api_logger.debug(text)
+        server.api_logger.debug(f"testauth/{text}")
 
 async def process(server: plugins.server.BaseServer, _session: dict, indata: dict) -> typing.Union[aiohttp.web.Response, dict]:
     debug(server, f'INDATA {indata}')
diff --git a/test/itest_integration.py b/test/itest_integration.py
index 6be4938..83b4f4d 100644
--- a/test/itest_integration.py
+++ b/test/itest_integration.py
@@ -38,10 +38,17 @@ def get_cookies(user='user'):
     state=random.randint(
         1000000000000000000,
         2000000000000000000) # roughly equivalent to code in oauth.js
-    testauth='testauth'
-    res = requests.get(f"{API_BASE}/{testauth}?state={state}&redirect_uri=x&state={state}&key=ignored",allow_redirects=False)
+    # Get the oauth settings (returned under 'oauth' key)
+    jzon_oauth = requests.get(f"{API_BASE}/preferences?oauth=1").json()
+    assert 'oauth' in jzon_oauth
+    testprovider='testprovider'
+    # get the url for the provider
+    oauth_portal = jzon_oauth['oauth'][testprovider]['oauth_portal']
+    assert oauth_portal
+    res = requests.get(f"{oauth_portal}?state={state}&redirect_uri=x&state={state}&key={testprovider}",allow_redirects=False)
     code = res.headers['Location'][1:]
-    res = requests.get(f"{API_BASE}/oauth.lua?key=ignored{code}&oauth_token={API_BASE}/{testauth}&state={state}&user={user}")
+    assert code.startswith('&code=')
+    res = requests.get(f"{API_BASE}/oauth.lua?key=testprovider&state={state}&user={user}{code}")
     cookies = res.cookies
     jzon = requests.get(f"{API_BASE}/preferences", cookies=cookies).json()
     assert 'credentials' in jzon['login']
diff --git a/webui/admin.html b/webui/admin.html
index 88f6a89..bfee83e 100644
--- a/webui/admin.html
+++ b/webui/admin.html
@@ -25,7 +25,7 @@ the License. -->
     <!-- Bootstrap -->
 
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1762148" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -79,9 +79,9 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1762148"></script>
-    <script src="js/wordcloud.js?revision=1762148"></script>
-    <script src="js/ponymail.js?revision=1762148"></script>
+    <script src="js/config.js?revision=1184382"></script>
+    <script src="js/wordcloud.js?revision=1184382"></script>
+    <script src="js/ponymail.js?revision=1184382"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
   </body>
diff --git a/webui/index.html b/webui/index.html
index 7ce489b..952bc6c 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -24,7 +24,7 @@ the License. -->
     <!-- Bootstrap -->
     
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1762148" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -63,8 +63,8 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1762148"></script>
-    <script src="js/ponymail.js?revision=1762148"></script>
+    <script src="js/config.js?revision=1184382"></script>
+    <script src="js/ponymail.js?revision=1184382"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
     
diff --git a/webui/js/config.js b/webui/js/config.js
index 47174da..f3c3c09 100644
--- a/webui/js/config.js
+++ b/webui/js/config.js
@@ -16,42 +16,6 @@
 */
 
 const pm_config = {
-    oauth: {
-        // OAuth settings
-         apache: {
-            name: "Apache OAuth",
-            oauth_portal: "https://oauth.apache.org/",
-            oauth_url: "https://oauth.apache.org/token",
-            fullname_key: 'fullname',
-            email_key: 'email'
-        },
-        google: {
-            name: "Google OAuth",
-            oauth_portal: "https://accounts.google.com/o/oauth2/auth",
-            oauth_url: "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=",
-            fullname_key: 'name',
-            email_key: 'email',
-            client_id: '41983040784-s1gl269f0p537r22h8eai2pdr1a94pfg.apps.googleusercontent.com'
-        },
-        github: {
-            name: "GitHub OAuth",
-            oauth_portal: "https://github.com/login/oauth/authorize",
-            client_id: "your-client-id-here",
-            scope: "user:email",
-            construct: true
-        },
-        // Enable the following lines for Docker testing
-        // user: {
-        //     name: "Test Auth User",
-        //     oauth_portal: "http://localhost:1080/api/testauth",
-        //     oauth_url: "http://localhost/api/testauth"
-        // },
-        // admin: {
-        //     name: "Test Auth Admin",
-        //     oauth_portal: "http://localhost:1080/api/testauth",
-        //     oauth_url: "http://localhost/api/testauth"
-        // },
-    },
     URLBase: '',
     apiURL: '/',
     boring_lists: ['commits', 'cvs', 'site-cvs', 'security', 'notifications'], // we'd rather not default to these, noisy!
diff --git a/webui/js/oauth.js b/webui/js/oauth.js
index 699460d..89c567e 100644
--- a/webui/js/oauth.js
+++ b/webui/js/oauth.js
@@ -15,6 +15,10 @@
  limitations under the License.
 */
 
+'use strict';
+
+let G_oauth = {};
+
 // Sometimes we don't need ponymail.js, so let's redefine GetAsync here
 function GetAsync(theUrl, xstate, callback) {
     let xmlHttp = null;
@@ -51,7 +55,7 @@ function GetAsync(theUrl, xstate, callback) {
 
 // redirect to the oauth provider
 function oauthPortal(key) {
-    let ot = pm_config.oauth[key]
+    let ot = G_oauth[key]
     let state = parseInt(Math.random()*1000000000) + '' + parseInt(Math.random()*1000000000)
     // google is different (as usual)
     if (key == 'google') {
@@ -77,13 +81,16 @@ function oauthPortal(key) {
 // page.
 function parseOauthResponse(json) {
     if (json.okay) {
+        console.log('Checking for origin URL');
         if (window.sessionStorage) {
             let url = window.sessionStorage.getItem('ponymail_oauth_origin');
+            console.log('Origin is ', url);
             if (url && url.length > 0) {
                 location.href = url;
                 return
             }
         }
+        console.log("No origin found, defaulting to ./");
         location.href = "./" // TODO: Return to whence we came...
     } else {
         alert("Oauth failed: Authentication failed: " + json.message)
@@ -97,8 +104,8 @@ function oauthOptions() {
     let oobj = document.getElementById('oauthtypes') 
     oobj.innerHTML = ""
     // For each enabled oauth plugin, list it.
-    for (let key in pm_config.oauth) {
-        let ot = pm_config.oauth[key]
+    for (let key in G_oauth) {
+        let ot = G_oauth[key]
         if (true) { // dunno why this is here, but whatever.
             let img = document.createElement('img')
             img.setAttribute("src", "images/oauth_" + key + ".png")
@@ -118,6 +125,13 @@ function oauthOptions() {
 // onLoad function for oauth. If args (query string or bookmark) are supplied,
 // we pass that on to the backend, otherwise show which oauth options are
 // enabled.
+function oauthInit(args) {
+    GetAsync(G_apiURL + "api/preferences.lua?oauth=true", {}, (json) => {
+        G_oauth = json['oauth'];
+        oauthWelcome(args, json);
+    } );
+}
+
 function oauthWelcome(args) {
     // google auth sometimes uses bookmarks instead of passing the code as a
     // query string arg.
@@ -138,9 +152,9 @@ function oauthWelcome(args) {
             key = 'google'
             args += "&key=google";
         }
-        if (key && key.length > 0 && pm_config.oauth[key]) {
+        if (key && key.length > 0 && G_oauth[key]) {
             document.getElementById('oauthtypes').innerHTML = "Logging you in, hang on..!"
-            GetAsync(G_apiURL + "api/oauth.lua?" + args + "&oauth_token=" + pm_config.oauth[key].oauth_url, {}, parseOauthResponse)
+            GetAsync(G_apiURL + "api/oauth.lua?" + args, {}, parseOauthResponse)
         } else {
             alert("Key missing or invalid! " + key)
         }
diff --git a/webui/js/ponymail.js b/webui/js/ponymail.js
index a6a5214..a319972 100644
--- a/webui/js/ponymail.js
+++ b/webui/js/ponymail.js
@@ -16,7 +16,7 @@
 */
 // THIS IS AN AUTOMATICALLY COMBINED FILE. PLEASE EDIT THE source/ FILES!
 
-const PONYMAIL_REVISION = '1762148';
+const PONYMAIL_REVISION = '1184382';
 
 
 /******************************************
diff --git a/webui/list.html b/webui/list.html
index 7437a0d..39f0e1d 100644
--- a/webui/list.html
+++ b/webui/list.html
@@ -24,7 +24,7 @@ the License. -->
     <!-- Bootstrap -->
     
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1762148" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -179,9 +179,9 @@ the License. -->
     </script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1762148"></script>
-    <script src="js/wordcloud.js?revision=1762148"></script>
-    <script src="js/ponymail.js?revision=1762148"></script>
+    <script src="js/config.js?revision=1184382"></script>
+    <script src="js/wordcloud.js?revision=1184382"></script>
+    <script src="js/ponymail.js?revision=1184382"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
     <script type="text/javascript">
diff --git a/webui/oauth.html b/webui/oauth.html
index 09925c0..81c35b2 100644
--- a/webui/oauth.html
+++ b/webui/oauth.html
@@ -21,7 +21,7 @@ the License. -->
 
     <!-- CSS -->
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1762148" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
 
@@ -32,7 +32,7 @@ the License. -->
       <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
     <![endif]-->
   </head>
-  <body style="margin: 0px;" onload="oauthWelcome(document.location.search.substr(1));">
+  <body style="margin: 0px;" onload="oauthInit(document.location.search.substr(1));">
     
     <div class="container-fluid">
       
@@ -54,8 +54,8 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1762148"></script>
-    <script src="js/ponymail.js?revision=1762148"></script>
-    <script src="js/oauth.js?revision=1762148"></script>
+    <script src="js/config.js?revision=1184382"></script>
+    <script src="js/ponymail.js?revision=1184382"></script>
+    <script src="js/oauth.js?revision=1184382"></script>
   </body>
 </html>
diff --git a/webui/thread.html b/webui/thread.html
index 786f4f0..9abfa3a 100644
--- a/webui/thread.html
+++ b/webui/thread.html
@@ -25,7 +25,7 @@ the License. -->
     <!-- Bootstrap -->
     
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1762148" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -97,9 +97,9 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1762148"></script>
-    <script src="js/wordcloud.js?revision=1762148"></script>
-    <script src="js/ponymail.js?revision=1762148"></script>
+    <script src="js/config.js?revision=1184382"></script>
+    <script src="js/wordcloud.js?revision=1184382"></script>
+    <script src="js/ponymail.js?revision=1184382"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
   </body>


(incubator-ponymail-foal) 05/09: Bump version

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit 0f78e6a83c56814e29d7cc117830eb77588fb9d1
Author: Sebb <se...@apache.org>
AuthorDate: Sun Feb 23 10:56:11 2025 +0000

    Bump version
---
 server/server_version.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/server_version.py b/server/server_version.py
index 4e89624..b032e44 100644
--- a/server/server_version.py
+++ b/server/server_version.py
@@ -1,2 +1,2 @@
 # This file is generated by server/update_version.sh
-PONYMAIL_SERVER_VERSION = '5a708d2'
+PONYMAIL_SERVER_VERSION = 'a1b4bd7'


(incubator-ponymail-foal) 09/09: Merge remote-tracking branch 'ponymail-foal/oauth-simplify'

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit 6660b94f7490ff8ebca9b4d6c4a9b6cf3b3898da
Merge: 8637f08 328bbcd
Author: Daniel Gruno <hu...@apache.org>
AuthorDate: Tue Dec 16 17:14:36 2025 +0100

    Merge remote-tracking branch 'ponymail-foal/oauth-simplify'

 .github/workflows/integration-tests.yml |  6 ++++
 server/endpoints/oauth.py               |  3 +-
 server/endpoints/preferences.py         |  6 ++++
 server/plugins/configuration.py         |  2 ++
 server/plugins/oauthGeneric.py          | 13 ++++---
 server/ponymail.yaml.example            | 61 +++++++++++++++++++++++++--------
 server/testendpoints/testauth.py        | 30 ++++++++--------
 test/itest_integration.py               | 13 +++++--
 webui/js/config.js                      | 36 -------------------
 webui/js/oauth.js                       | 24 ++++++++++---
 webui/oauth.html                        |  2 +-
 11 files changed, 114 insertions(+), 82 deletions(-)

diff --cc server/ponymail.yaml.example
index a9d27e3,0fd0571..a491e01
--- a/server/ponymail.yaml.example
+++ b/server/ponymail.yaml.example
@@@ -23,17 -24,47 +24,47 @@@ ui
  
  # Fill in OAuth data as needed
  oauth:
- # If using OAuth, set the authoritative domains here. These are the OAuth domains that 
- # will provide access to private emails.
- # N.B. This must be defined as an array (or omitted)
- # authoritative_domains:
- #   - localhost        # for local testing of sending email
- #    - googleapis.com  # OAuth via google is authoritative
- #    - github.com      # GitHub OAuth is authoritative
- # Set up users with administrative permission
- # N.B. This must be defined as an array (or omitted)
- # admins:
- #    - localtest@apache.org
- #  google_client_id:     ~
- #  github_client_id:     ~
- #  github_client_secret: ~
+   # Details of providers to be shown by the front end
+   # Note that there should be a corresponding icon at images/ouath_<key>.png
+   providers:
+     apache:
+       name:           Apache OAuth
+       oauth_portal:   https://oauth.apache.org/
+       .oauth_url:     https://oauth.apache.org/token
+       fullname_key:   fullname # does not appear to be used
+       email_key:      email
+     google:
+         name:         Google OAuth
+         oauth_portal: https://accounts.google.com/o/oauth2/auth
+         fullname_key: name # does not appear to be used
+         email_key:    email
 -        client_id:    41983040784-s1gl269f0p537r22h8eai2pdr1a94pfg.apps.googleusercontent.com
++        client_id:    foo-bar.apps.googleusercontent.com
+     github:
+         name:         GitHub OAuth
+         oauth_portal: https://github.com/login/oauth/authorize
+         client_id:    your-client-id-here
+         scope:        user:email
+         construct:    true # encode all the above keys
+     # Enable these for testing purposes (see testauth.py)
+     # user:
+     #   name:           Test Auth User
+     #   oauth_portal:   http://localhost:1080/api/testauth
+     #   .oauth_url:     http://localhost/api/testauth
+     # admin:
+     #   name:           Test Auth Admin
+     #   oauth_portal:   http://localhost:1080/api/testauth
+     #   .oauth_url:     http://localhost/api/testauth
+   # If using OAuth, set the authoritative domains here. These are the OAuth domains that
+   # will provide access to private emails.
+   # N.B. This must be defined as an array (or omitted)
+   # authoritative_domains:
+   #   - localhost        # for local testing of sending email
+   #    - googleapis.com  # OAuth via google is authoritative
+   #    - github.com      # GitHub OAuth is authoritative
+   # Set up users with administrative permission
+   # N.B. This must be defined as an array (or omitted)
+   # admins:
+   #    - localtest@apache.org
+   #  google_client_id:     ~
+   #  github_client_id:     ~
+   #  github_client_secret: ~


(incubator-ponymail-foal) 06/09: Run version tests last

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit fca3121cbb7ea072cd7d83ea058715947cd2894b
Author: Sebb <se...@apache.org>
AuthorDate: Sun Feb 23 10:57:08 2025 +0000

    Run version tests last
---
 .github/workflows/unittest.yml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml
index d1ee7af..84197da 100644
--- a/.github/workflows/unittest.yml
+++ b/.github/workflows/unittest.yml
@@ -41,10 +41,6 @@ jobs:
         # This only affects the appearance of the message body, so does not matter for compatibility
         pip install html2text==2020.1.16 # optional dependency, but needed for tests
         pip list
-    - name: Check versions
-      run: |
-        webui/js/source/build.sh
-        server/update_version.sh
     - name: Test with pytest
       run: |
         cp tools/archiver.yaml.example tools/archiver.yaml
@@ -54,3 +50,7 @@ jobs:
         sed -e '/incubator/s/# cropout:/cropout:/' tools/archiver.yaml.example >tools/archiver.yaml
         cd pmtests
         python runall.py --root ..
+    - name: Check versions
+      run: |
+        webui/js/source/build.sh
+        server/update_version.sh


(incubator-ponymail-foal) 02/09: Bump versions

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit cf09c901687676be0521d1f11fcb0951478a3504
Author: Sebb <se...@apache.org>
AuthorDate: Thu Jul 25 00:12:30 2024 +0100

    Bump versions
---
 server/server_version.py | 2 +-
 webui/admin.html         | 8 ++++----
 webui/index.html         | 6 +++---
 webui/js/ponymail.js     | 2 +-
 webui/list.html          | 8 ++++----
 webui/oauth.html         | 8 ++++----
 webui/thread.html        | 8 ++++----
 7 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/server/server_version.py b/server/server_version.py
index f49c017..4e89624 100644
--- a/server/server_version.py
+++ b/server/server_version.py
@@ -1,2 +1,2 @@
 # This file is generated by server/update_version.sh
-PONYMAIL_SERVER_VERSION = '3416ada'
+PONYMAIL_SERVER_VERSION = '5a708d2'
diff --git a/webui/admin.html b/webui/admin.html
index bfee83e..7e7ed5b 100644
--- a/webui/admin.html
+++ b/webui/admin.html
@@ -25,7 +25,7 @@ the License. -->
     <!-- Bootstrap -->
 
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=5a708d2" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -79,9 +79,9 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1184382"></script>
-    <script src="js/wordcloud.js?revision=1184382"></script>
-    <script src="js/ponymail.js?revision=1184382"></script>
+    <script src="js/config.js?revision=5a708d2"></script>
+    <script src="js/wordcloud.js?revision=5a708d2"></script>
+    <script src="js/ponymail.js?revision=5a708d2"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
   </body>
diff --git a/webui/index.html b/webui/index.html
index 952bc6c..e4cd4ff 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -24,7 +24,7 @@ the License. -->
     <!-- Bootstrap -->
     
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=5a708d2" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -63,8 +63,8 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1184382"></script>
-    <script src="js/ponymail.js?revision=1184382"></script>
+    <script src="js/config.js?revision=5a708d2"></script>
+    <script src="js/ponymail.js?revision=5a708d2"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
     
diff --git a/webui/js/ponymail.js b/webui/js/ponymail.js
index a319972..a6a5214 100644
--- a/webui/js/ponymail.js
+++ b/webui/js/ponymail.js
@@ -16,7 +16,7 @@
 */
 // THIS IS AN AUTOMATICALLY COMBINED FILE. PLEASE EDIT THE source/ FILES!
 
-const PONYMAIL_REVISION = '1184382';
+const PONYMAIL_REVISION = '1762148';
 
 
 /******************************************
diff --git a/webui/list.html b/webui/list.html
index 39f0e1d..6246089 100644
--- a/webui/list.html
+++ b/webui/list.html
@@ -24,7 +24,7 @@ the License. -->
     <!-- Bootstrap -->
     
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=5a708d2" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -179,9 +179,9 @@ the License. -->
     </script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1184382"></script>
-    <script src="js/wordcloud.js?revision=1184382"></script>
-    <script src="js/ponymail.js?revision=1184382"></script>
+    <script src="js/config.js?revision=5a708d2"></script>
+    <script src="js/wordcloud.js?revision=5a708d2"></script>
+    <script src="js/ponymail.js?revision=5a708d2"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
     <script type="text/javascript">
diff --git a/webui/oauth.html b/webui/oauth.html
index 81c35b2..99f29f7 100644
--- a/webui/oauth.html
+++ b/webui/oauth.html
@@ -21,7 +21,7 @@ the License. -->
 
     <!-- CSS -->
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=5a708d2" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
 
@@ -54,8 +54,8 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1184382"></script>
-    <script src="js/ponymail.js?revision=1184382"></script>
-    <script src="js/oauth.js?revision=1184382"></script>
+    <script src="js/config.js?revision=5a708d2"></script>
+    <script src="js/ponymail.js?revision=5a708d2"></script>
+    <script src="js/oauth.js?revision=5a708d2"></script>
   </body>
 </html>
diff --git a/webui/thread.html b/webui/thread.html
index 9abfa3a..1c833fb 100644
--- a/webui/thread.html
+++ b/webui/thread.html
@@ -25,7 +25,7 @@ the License. -->
     <!-- Bootstrap -->
     
     <link href="css/bootstrap.min.css" rel="stylesheet" media="all">
-    <link href="css/scaffolding.css?revision=1184382" rel="stylesheet" media="all">
+    <link href="css/scaffolding.css?revision=5a708d2" rel="stylesheet" media="all">
     <link href="css/modal.css" rel="stylesheet" media="all">
     <link href="css/spinner.css" rel="stylesheet" media="all">
     <link rel="alternate" href="/api/static.lua"/>
@@ -97,9 +97,9 @@ the License. -->
     <script src="js/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="></script>
     <!-- Include all compiled plugins (below), or include individual files as needed -->
     <script src="js/bootstrap.min.js"></script>
-    <script src="js/config.js?revision=1184382"></script>
-    <script src="js/wordcloud.js?revision=1184382"></script>
-    <script src="js/ponymail.js?revision=1184382"></script>
+    <script src="js/config.js?revision=5a708d2"></script>
+    <script src="js/wordcloud.js?revision=5a708d2"></script>
+    <script src="js/ponymail.js?revision=5a708d2"></script>
     <div id="splash" class="splash fade-in"> &nbsp; </div>
     <div style="clear: both;"></div>
   </body>


(incubator-ponymail-foal) 07/09: Check for invalid provider key - just in case

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit 44326c058225d6142962583007b7950ddbe4bb8b
Author: Sebb <se...@apache.org>
AuthorDate: Tue Oct 21 15:53:01 2025 +0100

    Check for invalid provider key - just in case
---
 server/plugins/oauthGeneric.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/server/plugins/oauthGeneric.py b/server/plugins/oauthGeneric.py
index 032259c..4563f23 100644
--- a/server/plugins/oauthGeneric.py
+++ b/server/plugins/oauthGeneric.py
@@ -24,8 +24,11 @@ import aiohttp.client
 
 
 async def process(formdata: dict, _session, server) -> typing.Optional[dict]:
-    provider = formdata["key"]
-    oauth_url = server.config.oauth.providers.get(provider).get('.oauth_url', '')
+    provider = server.config.oauth.providers.get(formdata["key"])
+    if not provider:
+        # should not happen, but just in case of client error
+        return aiohttp.web.Response(headers={}, status=404, text="OAuth provider not found")
+    oauth_url = provider.get('.oauth_url', '')
     # Extract domain, allowing for :port
     # Does not handle user/password prefix etc
     m = re.match(r"https?://([^/:]+)(?::\d+)?/", oauth_url)


(incubator-ponymail-foal) 04/09: Default to empty string, saving re.match from breaking

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

humbedooh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git

commit a1b4bd782216dab10dca16b407ff3d926e30a5af
Author: Daniel Gruno <hu...@apache.org>
AuthorDate: Tue Aug 6 18:37:36 2024 +0200

    Default to empty string, saving re.match from breaking
---
 server/plugins/oauthGeneric.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/plugins/oauthGeneric.py b/server/plugins/oauthGeneric.py
index 14818b8..032259c 100644
--- a/server/plugins/oauthGeneric.py
+++ b/server/plugins/oauthGeneric.py
@@ -25,7 +25,7 @@ import aiohttp.client
 
 async def process(formdata: dict, _session, server) -> typing.Optional[dict]:
     provider = formdata["key"]
-    oauth_url = server.config.oauth.providers.get(provider).get('.oauth_url')
+    oauth_url = server.config.oauth.providers.get(provider).get('.oauth_url', '')
     # Extract domain, allowing for :port
     # Does not handle user/password prefix etc
     m = re.match(r"https?://([^/:]+)(?::\d+)?/", oauth_url)