Hi Rob and all,
I attach here an example of an OIDC code grant flow implemented with RestXQ, BaseX permission and error handler. The file includes a sort of library for performing the steps of the OIDC flow plus a minimal application that is registered as public client inside keycloak and which is what you should access from your browser by calling http://localhost:8984/authtest or http://localhost:8984/authtest/internal. I've put into it also the logout procedure for performing the back-channel logout which closes the SSO session.

This is only a resume of a more generic and complex module but it should be useful as a howto and it should be as simple to install as copying the file to your BaseX' webapp folder. Use it as you like.
Regards,
Marco.

On 03/05/21 12:50, Rob wrote:
Hi Marco,

Got it!
Looking forward to the code! :)

With kind regards,
Rob

Op 3 mei 2021, om 09:23 heeft Marco Lettere <m.lett...@gmail.com <mailto:m.lett...@gmail.com>> het volgende geschreven:

Hi Rob,
no the code in the repository the link refers to is more like administrative tooling for batch importing configuration into Keycloak for administration purposes. I'll work on creating an excerpt of the code that realizes Oauth2 code grant flow with RestXQ and Keycloak and I'll share by tonight hopefully.
Regards,
Marco.

On 01/05/21 17:49, Rob wrote:
Hi all!

Sorry for the late response!
I’m reading all the emails now, haha.

I’m very happy to hear that it’s possible, I see you shared the following: https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery <https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery>

Thanks for sharing!

Based on the following quote from Marco’s mail:
"We have also a RestXQ module that in combination with basex:perm annotations protects access to a GUI implementing the Oauth2 Code-grant flow. If Rob is interested we could share.”

The link above, is that the RESTXQ module Marco’s been talking about?
Or is there another RESTXQ module?

With kind regards,
Rob

Op 1 mei 2021, om 05:29 heeft Adam Law <adamjames...@gmail.com <mailto:adamjames...@gmail.com>> het volgende geschreven:

If Rob isn't interested, I certain am... Yes please share

>>We have also a RestXQ module that in combination with basex:perm
annotations protects access to a GUI implementing the Oauth2 Code-grant
flow. If Rob is interested we could share.

Many thanks for sharing https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery <https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery>

This is a bit forward of me, but would you consider changing the license away from European Union Public Licence which appears to be 'copyleft' to say BSD 3-Clause, MIT, ...

Adam

On Fri, Apr 30, 2021 at 6:00 PM <basex-talk-requ...@mailman.uni-konstanz.de <mailto:basex-talk-requ...@mailman.uni-konstanz.de>> wrote:

    Send BaseX-Talk mailing list submissions to
    basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>

    To subscribe or unsubscribe via the World Wide Web, visit
    https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
    <https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk>
    or, via email, send a message with subject or body 'help' to
    basex-talk-requ...@mailman.uni-konstanz.de
    <mailto:basex-talk-requ...@mailman.uni-konstanz.de>

    You can reach the person managing the list at
    basex-talk-ow...@mailman.uni-konstanz.de
    <mailto:basex-talk-ow...@mailman.uni-konstanz.de>

    When replying, please edit your Subject line so it is more specific
    than "Re: Contents of BaseX-Talk digest..."


    Today's Topics:

       1. Make use of external Identity Management for BaseX (Rob)
       2. Re: Reloading jars on a running http server. (Reece Dunn)
       3. Getting profile information in server responses. (Reece Dunn)
       4. Re: Make use of external Identity Management for BaseX
          (Christian Gr?n)
       5. Re: Reloading jars on a running http server. (Christian Gr?n)
       6. Re: Getting profile information in server responses.
          (Christian Gr?n)
       7. Re: Reloading jars on a running http server. (Reece Dunn)
       8. Re: Reloading jars on a running http server. (Christian Gr?n)
       9. Re: Make use of external Identity Management for BaseX
          (Marco Lettere)


    ----------------------------------------------------------------------

    Message: 1
    Date: Thu, 29 Apr 2021 15:54:08 +0200
    From: Rob <priv...@tjalma.com <mailto:priv...@tjalma.com>>
    To: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: [basex-talk] Make use of external Identity Management for
            BaseX
    Message-ID: <39036ef3-e67d-470d-b2f4-e6fbffdf4...@tjalma.com
    <mailto:39036ef3-e67d-470d-b2f4-e6fbffdf4...@tjalma.com>>
    Content-Type: text/plain;  charset=utf-8

    Hi,

    I have a question.
    Can BaseX make use of an Identity Management application like
    Keycloak for Users?

    I can?t find anything about it :)

    With kind regards,
    Rob Tjalma

    ------------------------------

    Message: 2
    Date: Thu, 29 Apr 2021 20:48:09 +0100
    From: Reece Dunn <mscl...@googlemail.com
    <mailto:mscl...@googlemail.com>>
    To: Christian Gr?n <christian.gr...@gmail.com
    <mailto:christian.gr...@gmail.com>>
    Cc: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: Re: [basex-talk] Reloading jars on a running http server.
    Message-ID:
           
    <CAGdtn24Qdgbe3=nebya1je4hcrzvagi_serccrxstxmzcwc...@mail.gmail.com
    <mailto:nebya1je4hcrzvagi_serccrxstxmzcwc...@mail.gmail.com>>
    Content-Type: text/plain; charset="utf-8"

    Hi Christian,

    Thanks for the response. Unfortunately, I've not been able to
    get the
    reloading working.

    Kind regards,
    Reece

    On Wed, 21 Apr 2021 at 18:49, Christian Gr?n
    <christian.gr...@gmail.com <mailto:christian.gr...@gmail.com>>
    wrote:

    > Hi Reece,
    >
    > If you install your Java code as JAR file in the repository
    [1], the
    > code will be loaded and unloaded every time when your query is
    > executed. If you get an error message?
    >
    >  java.lang.reflect.InaccessibleObjectException: Unable to
    make field
    > private final jdk.internal.loader.URLClassPath
    > java.net.URLClassLoader.ucp accessible: module java.base does not
    > "opens java.net <http://java.net/>" to unnamed module @79e2c065
    >
    > ?unloading fails [2], as you?re probably using a more recent
    version
    > of the JDK, which restricts reflective access to internal
    variables.
    > You can get around this by adding Java flags at startup time:
    >
    >  --add-opens java.base/java.net <http://java.net/>=ALL-UNNAMED
    >  --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
    >
    > Maybe there are better solutions to unload JAR files today.
    > Suggestions are welcome!
    >
    > Hope this helps,
    > Christian
    >
    > [1] https://docs.basex.org/wiki/Repository#Java
    <https://docs.basex.org/wiki/Repository#Java>
    > [2]
    >
    
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34
    
<https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34>
    >
    >
    >
    > On Tue, Apr 20, 2021 at 6:44 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    > >
    > > Hi all,
    > >
    > > I'm working on a Java class that I'm importing into an
    XQuery, so I can
    > do additional processing on the data that isn't easily
    expressible in
    > XQuery (or XSLT). In order to get BaseX to pick up a modified
    version of
    > the jar file I'm building, I'm restarting the BaseX http server.
    > >
    > > This makes it slower to turn around testing the changes. Is
    there a
    > better way of doing this?
    > >
    > > Kind regards,
    > > Reece
    >
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL:
    
<http://mailman.uni-konstanz.de/pipermail/basex-talk/attachments/20210429/fba079e2/attachment-0001.htm
    
<http://mailman.uni-konstanz.de/pipermail/basex-talk/attachments/20210429/fba079e2/attachment-0001.htm>>

    ------------------------------

    Message: 3
    Date: Thu, 29 Apr 2021 20:50:40 +0100
    From: Reece Dunn <mscl...@googlemail.com
    <mailto:mscl...@googlemail.com>>
    To: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: [basex-talk] Getting profile information in server
    responses.
    Message-ID:
           
    <cagdtn26mnn7bu3bqun8pks1da4eq2tqstfonx5nqqevzpnh...@mail.gmail.com
    <mailto:cagdtn26mnn7bu3bqun8pks1da4eq2tqstfonx5nqqevzpnh...@mail.gmail.com>>
    Content-Type: text/plain; charset="utf-8"

    Hi all,

    In BaseX, is there a way to get the profile timings (compile,
    run, print,
    etc.) in the response of a HTTP request via the Server-Timing
    header (
    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
    <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing>)?

    Kind regards,
    Reece
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL:
    
<http://mailman.uni-konstanz.de/pipermail/basex-talk/attachments/20210429/12a4d4fa/attachment-0001.htm
    
<http://mailman.uni-konstanz.de/pipermail/basex-talk/attachments/20210429/12a4d4fa/attachment-0001.htm>>

    ------------------------------

    Message: 4
    Date: Fri, 30 Apr 2021 08:47:36 +0200
    From: Christian Gr?n <christian.gr...@gmail.com
    <mailto:christian.gr...@gmail.com>>
    To: Rob <priv...@tjalma.com <mailto:priv...@tjalma.com>>
    Cc: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: Re: [basex-talk] Make use of external Identity
    Management for
            BaseX
    Message-ID:
    <CAP94bnP_-nFY6BQv38gqQdy9aoFn_gtRzgM1rW+GB7yjr=x...@mail.gmail.com
    <mailto:x...@mail.gmail.com>>
    Content-Type: text/plain; charset="UTF-8"

    Hi Rob,

    There is no prepackaged module for Keycloak (at least I?m aware of
    none), but you can write your own code with XQuery. See [1] for an
    example how this might look like.

    Are you using RESTXQ?

    Best,
    Christian

    [1]
    
https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery
    
<https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery>



    On Thu, Apr 29, 2021 at 3:54 PM Rob <priv...@tjalma.com
    <mailto:priv...@tjalma.com>> wrote:
    >
    > Hi,
    >
    > I have a question.
    > Can BaseX make use of an Identity Management application like
    Keycloak for Users?
    >
    > I can?t find anything about it :)
    >
    > With kind regards,
    > Rob Tjalma


    ------------------------------

    Message: 5
    Date: Fri, 30 Apr 2021 08:48:36 +0200
    From: Christian Gr?n <christian.gr...@gmail.com
    <mailto:christian.gr...@gmail.com>>
    To: Reece Dunn <mscl...@googlemail.com
    <mailto:mscl...@googlemail.com>>
    Cc: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: Re: [basex-talk] Reloading jars on a running http server.
    Message-ID:
           
    <cap94bnns_gmotgxea2mp-fcjzqxio3hdzlfcg0_kknotrz6...@mail.gmail.com
    <mailto:cap94bnns_gmotgxea2mp-fcjzqxio3hdzlfcg0_kknotrz6...@mail.gmail.com>>
    Content-Type: text/plain; charset="UTF-8"

    Hi Reece,

    I?m sorry to hear that. Did you build a custom JAR file, or do you
    encounter problems with the JDK?

    Cheers,
    Christian



    On Thu, Apr 29, 2021 at 9:48 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    >
    > Hi Christian,
    >
    > Thanks for the response. Unfortunately, I've not been able to
    get the reloading working.
    >
    > Kind regards,
    > Reece
    >
    > On Wed, 21 Apr 2021 at 18:49, Christian Gr?n
    <christian.gr...@gmail.com <mailto:christian.gr...@gmail.com>>
    wrote:
    >>
    >> Hi Reece,
    >>
    >> If you install your Java code as JAR file in the repository
    [1], the
    >> code will be loaded and unloaded every time when your query is
    >> executed. If you get an error message?
    >>
    >>  java.lang.reflect.InaccessibleObjectException: Unable to
    make field
    >> private final jdk.internal.loader.URLClassPath
    >> java.net.URLClassLoader.ucp accessible: module java.base
    does not
    >> "opens java.net <http://java.net/>" to unnamed module @79e2c065
    >>
    >> ?unloading fails [2], as you?re probably using a more recent
    version
    >> of the JDK, which restricts reflective access to internal
    variables.
    >> You can get around this by adding Java flags at startup time:
    >>
    >>  --add-opens java.base/java.net <http://java.net/>=ALL-UNNAMED
    >>  --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
    >>
    >> Maybe there are better solutions to unload JAR files today.
    >> Suggestions are welcome!
    >>
    >> Hope this helps,
    >> Christian
    >>
    >> [1] https://docs.basex.org/wiki/Repository#Java
    <https://docs.basex.org/wiki/Repository#Java>
    >> [2]
    
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34
    
<https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34>
    >>
    >>
    >>
    >> On Tue, Apr 20, 2021 at 6:44 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    >> >
    >> > Hi all,
    >> >
    >> > I'm working on a Java class that I'm importing into an
    XQuery, so I can do additional processing on the data that
    isn't easily expressible in XQuery (or XSLT). In order to get
    BaseX to pick up a modified version of the jar file I'm
    building, I'm restarting the BaseX http server.
    >> >
    >> > This makes it slower to turn around testing the changes.
    Is there a better way of doing this?
    >> >
    >> > Kind regards,
    >> > Reece


    ------------------------------

    Message: 6
    Date: Fri, 30 Apr 2021 08:55:49 +0200
    From: Christian Gr?n <christian.gr...@gmail.com
    <mailto:christian.gr...@gmail.com>>
    To: Reece Dunn <mscl...@googlemail.com
    <mailto:mscl...@googlemail.com>>
    Cc: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: Re: [basex-talk] Getting profile information in server
            responses.
    Message-ID:
           
    <cap94bnmcyzqryvmejg7ekon+fjns0fsgwwx-_2eqrzzypv-...@mail.gmail.com
    
<mailto:cap94bnmcyzqryvmejg7ekon%2bfjns0fsgwwx-_2eqrzzypv-...@mail.gmail.com>>
    Content-Type: text/plain; charset="UTF-8"

    A good idea; I?ll think of ways to get this included. One challenge
    might be that the response is streamed to the client. This
    means that
    when creating the HTTP request headers, it will not be known
    yet how
    long the evaluation will take (and the time for evaluation may also
    depend on the connection speed). The time for parsing and compiling
    the query should be known at that time, though. ? Maybe we could
    suppress result streaming when timings are requested.


    On Thu, Apr 29, 2021 at 9:50 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    >
    > Hi all,
    >
    > In BaseX, is there a way to get the profile timings (compile,
    run, print, etc.) in the response of a HTTP request via the
    Server-Timing header
    (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
    <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing>)?
    >
    > Kind regards,
    > Reece


    ------------------------------

    Message: 7
    Date: Fri, 30 Apr 2021 08:14:21 +0100
    From: Reece Dunn <mscl...@googlemail.com
    <mailto:mscl...@googlemail.com>>
    To: Christian Gr?n <christian.gr...@gmail.com
    <mailto:christian.gr...@gmail.com>>
    Cc: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: Re: [basex-talk] Reloading jars on a running http server.
    Message-ID:
    <CAGdtn25JU3aGsHZepExgDigQX7asNDOF=2c6pwjcz1kgqqz...@mail.gmail.com
    <mailto:2c6pwjcz1kgqqz...@mail.gmail.com>>
    Content-Type: text/plain; charset="utf-8"

    Hi Christian,

    I'm not seeing any exceptions in the console window, even when
    enabling the
    debug setting. I'm using the AdoptOpenJDK 1.8. I also have
    AdoptOpenJDK 11,
    but I assume that will have the issue you described.

    It's a custom-built jar using Kotlin, built via gradle.

    One thing that it could be is that I'm using Kotlin objects
    (not classes),
    e.g.:

        package test
        object Test { fun f(): String = "test" }

    and using it like:

        declare namespace Test = "java:test.Test";

        declare function test:f() as xs:string {
            Test::f(Test::INSTANCE())
        };

    The build.gradle file is simple. It looks something like this
    (removing
    things like the junit configuration):

    -----
    buildscript {
        ext.kotlin_version = "1.4.32"
        ext.kotlin_stdlib = "kotlin-stdlib"
        ext.java_version = "1.8"

        repositories { mavenCentral() }
        dependencies { classpath
    "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }
    }

    apply plugin: 'kotlin'

    repositories {
        mavenCentral()
        mavenLocal()
    }

    compileKotlin { kotlinOptions { jvmTarget = java_version } }
    compileTestKotlin { kotlinOptions { jvmTarget = java_version } }

    dependencies {
        implementation
    "org.jetbrains.kotlin:$kotlin_stdlib:$kotlin_version"
    }
    -----

    You'll need to copy the kotlin-stdlib-1.4.32.jar file in
    addition to the
    test.jar file to BaseX's lib directory.

    Kind regards,
    Reece

    On Fri, 30 Apr 2021 at 07:48, Christian Gr?n
    <christian.gr...@gmail.com <mailto:christian.gr...@gmail.com>>
    wrote:

    > Hi Reece,
    >
    > I?m sorry to hear that. Did you build a custom JAR file, or
    do you
    > encounter problems with the JDK?
    >
    > Cheers,
    > Christian
    >
    >
    >
    > On Thu, Apr 29, 2021 at 9:48 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    > >
    > > Hi Christian,
    > >
    > > Thanks for the response. Unfortunately, I've not been able
    to get the
    > reloading working.
    > >
    > > Kind regards,
    > > Reece
    > >
    > > On Wed, 21 Apr 2021 at 18:49, Christian Gr?n
    <christian.gr...@gmail.com <mailto:christian.gr...@gmail.com>>
    > wrote:
    > >>
    > >> Hi Reece,
    > >>
    > >> If you install your Java code as JAR file in the
    repository [1], the
    > >> code will be loaded and unloaded every time when your query is
    > >> executed. If you get an error message?
    > >>
    > >>  java.lang.reflect.InaccessibleObjectException: Unable to
    make field
    > >> private final jdk.internal.loader.URLClassPath
    > >> java.net.URLClassLoader.ucp accessible: module java.base
    does not
    > >> "opens java.net <http://java.net/>" to unnamed module
    @79e2c065
    > >>
    > >> ?unloading fails [2], as you?re probably using a more
    recent version
    > >> of the JDK, which restricts reflective access to internal
    variables.
    > >> You can get around this by adding Java flags at startup time:
    > >>
    > >>  --add-opens java.base/java.net <http://java.net/>=ALL-UNNAMED
    > >>  --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
    > >>
    > >> Maybe there are better solutions to unload JAR files today.
    > >> Suggestions are welcome!
    > >>
    > >> Hope this helps,
    > >> Christian
    > >>
    > >> [1] https://docs.basex.org/wiki/Repository#Java
    <https://docs.basex.org/wiki/Repository#Java>
    > >> [2]
    >
    
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34
    
<https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34>
    > >>
    > >>
    > >>
    > >> On Tue, Apr 20, 2021 at 6:44 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>>
    > wrote:
    > >> >
    > >> > Hi all,
    > >> >
    > >> > I'm working on a Java class that I'm importing into an
    XQuery, so I
    > can do additional processing on the data that isn't easily
    expressible in
    > XQuery (or XSLT). In order to get BaseX to pick up a modified
    version of
    > the jar file I'm building, I'm restarting the BaseX http server.
    > >> >
    > >> > This makes it slower to turn around testing the changes.
    Is there a
    > better way of doing this?
    > >> >
    > >> > Kind regards,
    > >> > Reece
    >
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL:
    
<http://mailman.uni-konstanz.de/pipermail/basex-talk/attachments/20210430/1b9943e9/attachment-0001.htm
    
<http://mailman.uni-konstanz.de/pipermail/basex-talk/attachments/20210430/1b9943e9/attachment-0001.htm>>

    ------------------------------

    Message: 8
    Date: Fri, 30 Apr 2021 09:30:17 +0200
    From: Christian Gr?n <christian.gr...@gmail.com
    <mailto:christian.gr...@gmail.com>>
    To: Reece Dunn <mscl...@googlemail.com
    <mailto:mscl...@googlemail.com>>
    Cc: BaseX <basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>>
    Subject: Re: [basex-talk] Reloading jars on a running http server.
    Message-ID:
    <CAP94bnN5QnMVBoaNzAL8WOuUo7N8MDYbM4+z=3ftqdn_euv...@mail.gmail.com
    <mailto:3ftqdn_euv...@mail.gmail.com>>
    Content-Type: text/plain; charset="UTF-8"

    Hi Reece,

    > You'll need to copy the kotlin-stdlib-1.4.32.jar file in
    addition to the test.jar file to BaseX's lib directory.

    Please note that JAR libraries will only be unregistered after
    query
    evalution if they are moved into the repo directory. If a
    library is
    copied into the lib directory, it will be added to the static
    classpath.

    In the given case, you could probably keep
    kotlin-stdlib-1.4.32.jar in
    the lib directory, but you?ll need to keep your development code in
    the repository (as described in the Wiki). It?s no problem,
    though, to
    directly modify the repo code (you don?t have to use REPO
    INSTALL or
    repo:install for that).

    If the problem persists, feel free to send me a little
    test.jar, I can
    then do further testing.

    Hope this helps,
    Christian


    On Fri, Apr 30, 2021 at 9:14 AM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    >
    > Hi Christian,
    >
    > I'm not seeing any exceptions in the console window, even
    when enabling the debug setting. I'm using the AdoptOpenJDK
    1.8. I also have AdoptOpenJDK 11, but I assume that will have
    the issue you described.
    >
    > It's a custom-built jar using Kotlin, built via gradle.
    >
    > One thing that it could be is that I'm using Kotlin objects
    (not classes), e.g.:
    >
    >     package test
    >     object Test { fun f(): String = "test" }
    >
    > and using it like:
    >
    >     declare namespace Test = "java:test.Test";
    >
    >     declare function test:f() as xs:string {
    >         Test::f(Test::INSTANCE())
    >     };
    >
    > The build.gradle file is simple. It looks something like this
    (removing things like the junit configuration):
    >
    > -----
    > buildscript {
    >     ext.kotlin_version = "1.4.32"
    >     ext.kotlin_stdlib = "kotlin-stdlib"
    >     ext.java_version = "1.8"
    >
    >     repositories { mavenCentral() }
    >     dependencies { classpath
    "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }
    > }
    >
    > apply plugin: 'kotlin'
    >
    > repositories {
    >     mavenCentral()
    >     mavenLocal()
    > }
    >
    > compileKotlin { kotlinOptions { jvmTarget = java_version } }
    > compileTestKotlin { kotlinOptions { jvmTarget = java_version } }
    >
    > dependencies {
    >     implementation
    "org.jetbrains.kotlin:$kotlin_stdlib:$kotlin_version"
    > }
    > -----
    >
    > You'll need to copy the kotlin-stdlib-1.4.32.jar file in
    addition to the test.jar file to BaseX's lib directory.
    >
    > Kind regards,
    > Reece
    >
    > On Fri, 30 Apr 2021 at 07:48, Christian Gr?n
    <christian.gr...@gmail.com <mailto:christian.gr...@gmail.com>>
    wrote:
    >>
    >> Hi Reece,
    >>
    >> I?m sorry to hear that. Did you build a custom JAR file, or
    do you
    >> encounter problems with the JDK?
    >>
    >> Cheers,
    >> Christian
    >>
    >>
    >>
    >> On Thu, Apr 29, 2021 at 9:48 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    >> >
    >> > Hi Christian,
    >> >
    >> > Thanks for the response. Unfortunately, I've not been able
    to get the reloading working.
    >> >
    >> > Kind regards,
    >> > Reece
    >> >
    >> > On Wed, 21 Apr 2021 at 18:49, Christian Gr?n
    <christian.gr...@gmail.com <mailto:christian.gr...@gmail.com>>
    wrote:
    >> >>
    >> >> Hi Reece,
    >> >>
    >> >> If you install your Java code as JAR file in the
    repository [1], the
    >> >> code will be loaded and unloaded every time when your
    query is
    >> >> executed. If you get an error message?
    >> >>
    >> >>  java.lang.reflect.InaccessibleObjectException: Unable to
    make field
    >> >> private final jdk.internal.loader.URLClassPath
    >> >> java.net.URLClassLoader.ucp accessible: module java.base
    does not
    >> >> "opens java.net <http://java.net/>" to unnamed module
    @79e2c065
    >> >>
    >> >> ?unloading fails [2], as you?re probably using a more
    recent version
    >> >> of the JDK, which restricts reflective access to internal
    variables.
    >> >> You can get around this by adding Java flags at startup time:
    >> >>
    >> >>  --add-opens java.base/java.net
    <http://java.net/>=ALL-UNNAMED
    >> >>  --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
    >> >>
    >> >> Maybe there are better solutions to unload JAR files today.
    >> >> Suggestions are welcome!
    >> >>
    >> >> Hope this helps,
    >> >> Christian
    >> >>
    >> >> [1] https://docs.basex.org/wiki/Repository#Java
    <https://docs.basex.org/wiki/Repository#Java>
    >> >> [2]
    
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34
    
<https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/util/JarLoader.java#L34>
    >> >>
    >> >>
    >> >>
    >> >> On Tue, Apr 20, 2021 at 6:44 PM Reece Dunn
    <mscl...@googlemail.com <mailto:mscl...@googlemail.com>> wrote:
    >> >> >
    >> >> > Hi all,
    >> >> >
    >> >> > I'm working on a Java class that I'm importing into an
    XQuery, so I can do additional processing on the data that
    isn't easily expressible in XQuery (or XSLT). In order to get
    BaseX to pick up a modified version of the jar file I'm
    building, I'm restarting the BaseX http server.
    >> >> >
    >> >> > This makes it slower to turn around testing the
    changes. Is there a better way of doing this?
    >> >> >
    >> >> > Kind regards,
    >> >> > Reece


    ------------------------------

    Message: 9
    Date: Fri, 30 Apr 2021 09:37:14 +0200
    From: Marco Lettere <m.lett...@gmail.com
    <mailto:m.lett...@gmail.com>>
    To: basex-talk@mailman.uni-konstanz.de
    <mailto:basex-talk@mailman.uni-konstanz.de>
    Subject: Re: [basex-talk] Make use of external Identity
    Management for
            BaseX
    Message-ID: <1a8d807b-9cb3-3cd4-f1b7-22aff5446...@gmail.com
    <mailto:1a8d807b-9cb3-3cd4-f1b7-22aff5446...@gmail.com>>
    Content-Type: text/plain; charset=utf-8; format=flowed

    Hi Christian and Rob,
    as the authors of the code you point to we confirm that
    interacting with
    Keycloak in XQuery and in particular RestXQ is rather comfortable.
    That example is mostly a demonstration code for a tool that
    scrapes a
    site index and registers sites named gateways as public clients
    (in
    Oauth2 sense) into a Keycloak instance.
    It is a proof of concept (as you can see from the credentials?
    :-D) that
    has been used as a batch one-time migration in a particular
    setting.

    We have also a RestXQ module that in combination with basex:perm
    annotations protects access to a GUI implementing the Oauth2
    Code-grant
    flow. If Rob is interested we could share.

    If there should be any plan of integrating Oauth2/OIDC flows more
    tightly into BaseX we could also be available for helping out.

    Regards,
    Marco.

    On 30/04/21 08:47, Christian Gr?n wrote:
    > Hi Rob,
    >
    > There is no prepackaged module for Keycloak (at least I?m
    aware of
    > none), but you can write your own code with XQuery. See [1]
    for an
    > example how this might look like.
    >
    > Are you using RESTXQ?
    >
    > Best,
    > Christian
    >
    > [1]
    
https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery
    
<https://code-repo.d4science.org/gCubeSystem/d4science-keycloak-themes/src/branch/master/src/utils/xquery>
    >
    >
    >
    > On Thu, Apr 29, 2021 at 3:54 PM Rob <priv...@tjalma.com
    <mailto:priv...@tjalma.com>> wrote:
    >> Hi,
    >>
    >> I have a question.
    >> Can BaseX make use of an Identity Management application
    like Keycloak for Users?
    >>
    >> I can?t find anything about it :)
    >>
    >> With kind regards,
    >> Rob Tjalma




    End of BaseX-Talk Digest, Vol 136, Issue 17
    *******************************************





module namespace auth = 'urn:nubisware:muscle:fiber:auth';
import module namespace session = "http://basex.org/modules/session";;

declare namespace b64 = "java:java.util.Base64";
declare namespace b64enc = "java:java.util.Base64$Encoder";
declare namespace b64dec = "java:java.util.Base64$Decoder";

declare variable $auth:config := map {
  "keycloakurl" : "https://mykeycloak.org";,
  "realm" : "myrealm",
  "clientid" : "myexamplepublicclient",
  "client_redirect_uri" : "http://localhost:8984/auth/oidc-callback";
};

declare %private variable $auth:KEYCLOAK_BASE_URL := 
  $auth:config?keycloakurl || "/auth/realms/" || $auth:config?realm || 
"/protocol/openid-connect";
declare %private variable $auth:KEYCLOAK_TOKEN_URL := $auth:KEYCLOAK_BASE_URL 
|| "/token";
declare %private variable $auth:KEYCLOAK_LOGOUT_URL := $auth:KEYCLOAK_BASE_URL 
|| "/logout";
declare %private variable $auth:KEYCLOAK_AUTH_URL := $auth:KEYCLOAK_BASE_URL || 
"/auth";


declare function auth:hex-to-base64url($tbe as xs:hexBinary) {
  auth:bytes-to-base64url(convert:binary-to-bytes($tbe))
};

declare function auth:bytes-to-base64url($tbe as xs:byte*) {
  b64enc:encodeToString(b64:getUrlEncoder(), $tbe)
};

declare function auth:extract-tokens-from-jwt($jwt as node()) as map(*){
  let $b64decoder := b64:getDecoder()
  let $t1 := $jwt/json/access__token/string()
  let $t2 := tokenize($t1, "\.")[2]
  let $t3 := 
convert:binary-to-string(convert:integers-to-base64(b64dec:decode($b64decoder, 
$t2)))
  let $at := json:parse($t3)
  let $t := $jwt/json/refresh__token/string()
  return map{ "accesstoken" : $at, "refreshtoken" : $t, "bearer" : "Bearer " || 
$t1}
};


(: You can just raise an error with code aut:unauthorized from anywhere in your 
code to get here and be redirected to keycloak:)
declare
  %rest:error("auth:unauthorized")
  %rest:error-param("value", "{$value}")
function auth:unauthorized($value as map(*)?) {
  web:redirect(web:create-url("/auth/login", $value))
};

(: Start OIDC login with code grant flow this makes it unnecessary to share 
secrets with a front facing application :)
declare
  %rest:path("auth/login")
  %rest:GET
  %rest:query-param("error", "{$error}")
  %rest:query-param("redirect", "{$redirect}", "/")
  %output:method("html")
function auth:login-show-ep($error as xs:string?, $redirect as xs:string) { 
  let $params := map{
    "client_id" : $auth:config?clientid, "response_type" : "code", "scope" : 
"openid",
    "state" : ($redirect, "/")[1],
    "redirect_uri" : $auth:config?client_redirect_uri
  }
  return web:redirect(web:create-url($auth:KEYCLOAK_AUTH_URL , $params))
};

(: That's the call back uri you will be redirected back after inserting your 
credentials in Keycloak :)
declare
  %rest:path("auth/oidc-callback")
  %rest:GET
  %rest:query-param("error", "{$error}")
  %rest:query-param("error_description", "{$error-description}")
  %rest:query-param("session_state", "{$session-state}")
  %rest:query-param("state", "{$state}")
  %rest:query-param("code", "{$code}")
  %output:method("html")
function auth:oidc-redirects(
    $error as xs:string?, $error-description as xs:string?,
    $session-state as xs:string?, $code as xs:string?, $state
) { 
  if(exists($error)) then 
   error("Unable to connect to auth service: " || $error-description)
  else   
     let $body := web:create-url("",
     map{
       "grant_type" : "authorization_code",
       "code" : $code,
       "redirect_uri" : $auth:config?client_redirect_uri,
       "client_id" : $auth:config?clientid,
       "scope" : "openid"
     })
     let $token-response := http:send-request(
       <http:request method="POST" href="{$auth:KEYCLOAK_TOKEN_URL}">
         <http:body 
media-type="application/x-www-form-urlencoded">{substring-after($body, 
"?")}</http:body>
       </http:request>
     )
     return
       if($token-response[1]/@status != "200") then
         error("Unable to authorize")
       else
         (session:set("principal", ($token-response[2])), web:redirect($state))
};

(: Logout may be just closing the local session but I added also an example for 
making a backchannel logout thus closing also the SSO session on Keycloak. Note 
that I am using the original requested url in the state parameter in order to 
be able to redirect to the requeste d page. Maybe it should be encoded and 
randomized... :)
declare
  %rest:path("auth/logout")
  %rest:POST
  %rest:form-param("redirect", "{$redirect}", "/")
  %output:method("html")
function auth:logout-ep($redirect as xs:string) { 
  let $tokens := auth:extract-tokens-from-jwt(session:get("principal"))
  let $bearer := $tokens?bearer
  let $refresh := $tokens?refreshtoken
   let $body := web:create-url("",
      map{
       "refresh_token" : $refresh,
       "client_id" : $auth:config?clientid,
       "redirect_uri" : $auth:config?client_redirect_uri
     })
   let $logout := http:send-request(
     <http:request method="POST" href="{$auth:KEYCLOAK_LOGOUT_URL}">
       <http:header name="Authorization" value="{$bearer}"></http:header>
       <http:body 
media-type="application/x-www-form-urlencoded">{substring-after($body, 
"?")}</http:body>
     </http:request>
   )
   return
      (
        session:close(),
        web:redirect($redirect)
      )
};

(: The following code represents an example application that you can access at 
http://localhost:8984/authtest.
   Two example pages a frontpage and an internal page. Both should be protected 
:)
declare %private %basex:inline function auth:home-page(){
   <html>
    <head>
      <title>Login</title>
    </head>
    <body>
      <h1>Hello Auth Test</h1>
      <h2>Principal: {session:get("principal") ! json:serialize(.)}</h2>
      <form action="/auth/logout" method="POST">
        <input type="hidden" name="redirect" value="/authtest"/>
        <input type="submit" name="submit" value="Logout"/>
      </form>
    </body>
  </html>
};

declare %private %basex:inline function auth:internal-page(){
   <html>
    <head>
      <title>Internal</title>
    </head>
    <body>
      <h1>This is an internal page</h1>
      <h2>Principal: {json:serialize(session:get("principal"))}</h2>
      <a href="/authtest/">Back</a>
      <form action="/auth/logout" method="POST">
        <input type="hidden" name="redirect" value="/authtest"/>
        <input type="submit" name="submit" value="Logout"/>
      </form>
    </body>
  </html>
};

(: This is the permission check on every page of the example application 
authtest:)
declare %perm:check("/authtest", "{$context}") function 
auth:access-control($context as map(*)){
  let $principal := session:get("principal")
  return 
    if(empty($principal)) then error(xs:QName("auth:unauthorized"),"",map{ 
"redirect" : $context?path})
    else ()
};

(: The example application authtest endpoints:)
declare
  %rest:path("/authtest")
  %rest:GET
  %output:method("html")
function auth:home-page-endpoint() { 
  auth:home-page()
};

declare
  %rest:path("/authtest/internal")
  %rest:GET
  %output:method("html")
function auth:internal-page-endpoint() { 
  auth:internal-page()
};

Reply via email to