andstatus / andstatus

Multiple accounts client for multiple Social networks. For Android
http://andstatus.org/
Apache License 2.0
307 stars 69 forks source link

adding an activityPub Account to andStatus #548

Closed naturzukunft closed 2 years ago

naturzukunft commented 2 years ago

Hi there, i've now implemented webfinger, see:
https://webfinger.net/lookup/?resource=mschlosser%40rdfpub.test.opensourceecology.de But i cannot add 'mschlosser@rdfpub.test.opensourceecology.de' to andStatus.

Whats wrong ? Thanks Fredy

naturzukunft commented 2 years ago

ok, i found a POST request in the log: /api/v1/apps that must be from andStatus ?!

naturzukunft commented 2 years ago

maybe you expect that: https://docs.joinmastodon.org/methods/apps/ But that is not really activityPub related, isn't it?

something unspecified in C2S ?

yvolk commented 2 years ago

Hi @naturzukunft AndStatus doesn't use webfinger lookups, please see here on this: https://github.com/andstatus/andstatus/issues/528#issuecomment-816535421

naturzukunft commented 2 years ago

Hi @yvolk , that's fine! How can i connect andStatus to my activityPub C2S Server? Is there somewhere a short how to? Did you see the comments https://github.com/andstatus/andstatus/issues/548#issuecomment-1007998444 and https://github.com/andstatus/andstatus/issues/548#issuecomment-1007999526 Thanks Fredy

naturzukunft commented 2 years ago

I have now read something in https://github.com/andstatus/andstatus/issues/499, there is a lot there, but not so much concretely useful. You might think that AndStatus uses Oauth2 Dynamic Client registration, but I'm not sure. It would be nice to know what AndStatus expects before I do try & error for days. My test server works with a keycloak oauth2 server. so all probably "just" a matter of configuration. But in AndStatus I have very few configuration options. there I can only specify an ActivityPub Id. but what exactly is an ActivityPub Id ? the server that should be included in this id should be the auth server. but how does andstatus then know my resource server? ok, that could possibly run via a redirect. I admit that I am not an oauth2 expert.

yvolk commented 2 years ago

Hello @naturzukunft Yes, AndStatus uses dynamic Client registration for ActivityPub.

  1. In order to fix AndStatus connection problems to your ActivityPub server AndStatus app own logs are very useful. They will allow us to see exact step, URLs and payloads that caused a problem... Please see https://github.com/andstatus/andstatus/issues/225 for tips on configuring and getting logs from Android device.

  2. In this thread we are currently doing the same thing with another developer: https://github.com/andstatus/andstatus/issues/549 I even extended logging in AndStatus to show concrete problem in a place, where there was no detailed errors earlier (See and use Alpha build from there...)

So you don't need anything except Android device for this testing.

Looking at Android device's UI and into the logs we will be able to discuss concrete problem/behavior without investigation of different OAuth specifications...

naturzukunft commented 2 years ago

@yvolk where do i find the settings for logging:

yvolk commented 2 years ago

@naturzukunft Settings -> Scroll down to Troubleshooting -> click Troubleshooting

naturzukunft commented 2 years ago
01-17 12:50:08.751 V/MySettingsActivity91: onPause; ; settingsGroup:SettingsFragment:unknown
01-17 12:50:08.764 V/MyContextImpl38: setExpired Release Initialization: Preferences changed, previous:MyContextImpl38 by MySettingsActivity91
01-17 12:50:08.790 D/MyFutureContext: Release completed, Initialization: Preferences changed, previous:MyContextImpl38 by MySettingsActivity91
01-17 12:50:08.798 I/MyContextImpl103: Starting initialization by MySettingsActivity91
01-17 12:50:08.825 I/MyContextImpl103: databaseInitializedMs: 15; DATABASE_READY
01-17 12:50:08.839 V/PersistentOrigins: Initialized 14 origins
01-17 12:50:08.856 I/CachedUsersAndActors: usersInitializedMs:10; 0 users, 0 my actors, 0 friends, 0 followers
01-17 12:50:08.862 I/MyAccounts: accountsInitializedMs:0; 0 accounts in 0 origins
01-17 12:50:08.868 I/PersistentTimelines: timelinesInitializedMs:1; 0 timelines
01-17 12:50:08.879 I/ImageCaches: imageCachesInitializedMs:4; ImageCaches: Avatars: 96x96, 0 of 273, free: 275, hits:0, misses:0; Attached images: 960x960, 0 of 11, free: 13, hits:0, misses:0; Styled images: 0; Memory. App total: 192MB; Device: available 1479MB of 3546MB
01-17 12:50:08.887 D/CommandQueue: loadQueue-current; loaded 0 commands from 'CURRENT'
01-17 12:50:08.894 D/CommandQueue: loadQueue-downloads; loaded 0 commands from 'DOWNLOADS'
01-17 12:50:08.903 D/CommandQueue: loadQueue-skipped; loaded 0 commands from 'SKIPPED'
01-17 12:50:08.909 D/CommandQueue: loadQueue-retry; loaded 0 commands from 'RETRY'
01-17 12:50:08.917 D/CommandQueue: loadQueue-error; loaded 0 commands from 'ERROR'
01-17 12:50:08.921 I/CommandQueue: commandQueueInitializedMs:36; no msg in queues
01-17 12:50:08.931 I/Notifier: notifierInitializedMs:4; 0 events
01-17 12:50:08.937 V/MyServiceManager: Service is unavailable: Context is not Ready: MyContextImpl38 by FirstActivity31; state=EXPIRED; expired; 0 accounts, context=org.andstatus.app.context.MyApplication
01-17 12:50:08.942 I/MyContextImpl103: myContextInitializedMs:143; READY by MySettingsActivity91
01-17 12:50:08.947 D/MyFutureContext99: whenSuccessAsync MyContextImpl103 by MySettingsActivity91; state=READY; 0 accounts, context=org.andstatus.app.context.MyApplication, java.util.concurrent.CompletableFuture@8dbe41[Completed normally]
01-17 12:50:08.952 I/MyApplication: startApp
01-17 12:50:09.010 I/FirstActivity104: No AndStatus Accounts yet
01-17 12:50:09.023 V/HelpActivity: Finishing FirstActivity and starting me
01-17 12:50:09.051 V/HelpActivity105: onCreate
01-17 12:50:09.056 V/HelpActivity105: getStyleId; name:"Theme.AndStatus.DeviceDefault"; id:7f1101cb; default:7f1101cd
01-17 12:50:11.526 V/HelpActivity105: finish: DONE
01-17 12:50:11.558 V/AccountSettingsActiv106: onCreate
01-17 12:50:11.563 V/AccountSettingsActiv106: getStyleId; name:"Theme.AndStatus.DeviceDefault"; id:7f1101cb; default:7f1101cd
01-17 12:50:11.578 V/AccountData109: new from / and jso: {
  "account": "\/"
}
01-17 12:50:11.584 V/AccountSettingsActiv106: restoreState from onActivityCreated; No previous state; Old completed, New state; action=android.intent.action.VIEW; intent=#Intent;launchFlags=0x10000000;component=org.andstatus.app/.account.AccountSettingsActivity;end
01-17 12:50:11.592 V/AccountSettingsActiv106: getStyleId; name:"Theme.AndStatus.DeviceDefault"; id:7f1101cb; default:7f1101cd
01-17 12:50:11.609 V/AccountSettingsActiv106: onResume: android.intent.action.VIEW, MyAccount: {(invalid) accountName:(invalid) /,not persistent,OAuth,verified:NEVER,connection:empty,syncable,syncauto}
01-17 12:50:11.616 V/AccountSettingsActiv106: No fragment found
01-17 12:50:13.937 V/AccountData110: new from /ActivityPub and jso: {
  "account": "\/ActivityPub",
  "origin_name": "ActivityPub"
}
01-17 12:50:13.947 V/OAuthClientKeysDynamic: OriginUrl is null; HttpConnectionData {(invalid) /ActivityPub, isSsl:true, sslMode:SSL mode:SECURE, basicPath:api, oauthPath:oauth, originUrl:null, hostForUserToken:null, dataReader:org.andstatus.app.account.AccountData@3dd629bf, oauthClientKeys:null}
01-17 12:50:13.953 D/OAuthClientKeys: Loaded OAuthClientKeysDynamic-; No keys
01-17 12:50:55.487 V/AccountSettingsActiv106: onResume: android.intent.action.VIEW, MyAccount: {(invalid) accountName:(invalid) /ActivityPub,not persistent,OAuth,verified:NEVER,syncable,syncauto}
01-17 12:50:59.154 V/AccountData111: new from mschlosser@rdfpub.test.opensourceecology.de/ActivityPub and jso: {
  "account": "mschlosser@rdfpub.test.opensourceecology.de\/ActivityPub",
  "origin_name": "ActivityPub",
  "username": "mschlosser",
  "unique_name": "mschlosser@rdfpub.test.opensourceecology.de"
}
01-17 12:50:59.167 V/MyQuery: actorwebfinger_idToId; 0+mschlosser@rdfpub.test.opensourceecology.de -> 0
01-17 12:50:59.174 D/OAuthClientKeys: Loaded OAuthClientKeysDynamic-17-rdfpub.test.opensourceecology.de; No keys
01-17 12:50:59.187 V/AccountSettingsActiv106: Launching OAuthRegisterClientT112 on QUICK_UI, age: 0 ms, PENDING: 0 ms, instanceId: 112
01-17 12:50:59.219 V/MyAccountBuilder: Registering client application for mschlosser
01-17 12:50:59.226 D/OAuthClientKeys: Loaded OAuthClientKeysDynamic-17-rdfpub.test.opensourceecology.de; No keys
01-17 12:50:59.234 V/HttpConnectionOAuthMast: registerClient; for https://rdfpub.test.opensourceecology.de; URL='https://rdfpub.test.opensourceecology.de/api/v1/apps'
01-17 12:50:59.240 D/OAuthClientKeys: Saved OAuthClientKeysDynamic-17-rdfpub.test.opensourceecology.de; No keys
01-17 12:50:59.417 D/OAuthRegisterClientT112: AndStatus
01-17 12:50:59.439 V/OAuthRegisterClientT112:  failed
naturzukunft commented 2 years ago

How is AndStatus deciding to use " URL='https://rdfpub.test.opensourceecology.de/api/v1/apps'" ? Shouldn't it get the register endpoint from a well-known site ? https://login.m4h.network/auth/realms/LOA/.well-known/openid-configuration

yvolk commented 2 years ago

So far looks exactly like in #549 Please use Alpha build from that thread to see more + to see error in UI.

naturzukunft commented 2 years ago

Ok, thats is not as easy, on the device where i have an external sd card and logging (lineageOs) i'm not able to install the aplha. on another device with standard google android apha is insatlled now.

grafik

But i didn't implement an "/api/v1/apps'" endpoint !

naturzukunft commented 2 years ago

i have to understand the used oauth2 flow!

i'm usind a keycloak instance as oauth2 identityProvider. It provides this endpoint: https://login.m4h.network/auth/realms/LOA/.well-known/openid-configuration where you can find the regsitration endpoint: https://login.m4h.network/auth/realms/LOA/clients-registrations/openid-connect

I see, that AndStatus cannot know that i'm using that keycloak instance and would understand that i have to provide an endpoint like https://rdfpub.test.opensourceecology.de/.well-known/openid-configuration

info: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig

naturzukunft commented 2 years ago

it might make more sense to define a ".well-known/activityPub" endpoint, which then provides the "issuer".

https://rdfpub.test.opensourceecology.de/.well-known/activityPub:

{
    "issuer":"https://login.m4h.network/auth/realms/LOA"
}
yvolk commented 2 years ago

From the first sight "/.well-known/activityPub" URL looks like another hardcoded URL for me. Not better than "/api/v1/apps". Any references in ActivityPub specs for that?

Regarding "/api/v1/apps" - this is simply what already works in existing server implementations...

naturzukunft commented 2 years ago

Info: https://socialhub.activitypub.rocks/t/authentication-authorization-oauth2/2235

regarding "/.well-known/activityPub" you are absolutely right! It doesn't matter which path to use, but the community should define one ;-)

But ".well-known/openid-configuration" is a standard. And the standard behind "/api/v1/apps" i didn't know yet.

Anyhow, i'll will watch https://conf.tube/videos/watch/32351956-89d7-4887-b6b0-f1a32f91dc36?start=1m26s to see what Aaron Parecki is telling us.

naturzukunft commented 2 years ago

Did you know/use https://github.com/openid/AppAuth-Android ?

naturzukunft commented 2 years ago

Puh, i think i've to sleep a few nights about that topic. In my setup the activity-pub server is a resource-server and it is related to the authentication server just with a url. I don't want to have any authorisation logic in the activity-pub resource server, at most a forwarding of the .well-known/openid-configuration information. i will try to read up a bit on https://indieauth.net/.

First of all, many thanks for the support up to here

yvolk commented 2 years ago

And the standard behind "/api/v1/apps" i didn't know yet.

Just Mastodon's choice, as I know. It looks ugly to me as a "Client Registration endpoint".

Did you know/use https://github.com/openid/AppAuth-Android ?

No. Actually, I investigated OAuth2 to the point I felt needed to implement it in a simple and more or less standard way...

regarding "/.well-known/activityPub" you are absolutely right! It doesn't matter which path to use, but the community should define one ;-)

Non-normative examples: in the RFC7591 https://datatracker.ietf.org/doc/html/rfc7591#section-3.1 uses "/register" as the Client Registration Endpoint... in the OpenID-connect https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest uses "/connect/register"

naturzukunft commented 2 years ago

Non-normative examples: in the RFC7591 https://datatracker.ietf.org/doc/html/rfc7591#section-3.1 uses "/register" as the Client Registration Endpoint... in the OpenID-connect https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest uses "/connect/register"

What doesn't matter, if they are behind the "registration_endpoint" property of OAuth 2.0 Authorization Server Metadata

Even "https://mastodon.sample/api/v1/apps" can be the value of "registration_endpoint" ! And then there is an abstraction and the resource-server can delegate the registration to an auth-server.

But if an app expect the registration-endpoint without a step between (like 'Server Metadata') the resource-server has to handle the registration, which is not it's work.

Fredy

yvolk commented 2 years ago

Reading your link to RFC8414 I got that before trying to register Client at a server using hardcoded path (e.g. "/api/v1/apps") a Client app should call (according to section 3 of RFC8414 https://datatracker.ietf.org/doc/html/rfc8414#section-3 ):

"/.well-known/oauth-authorization-server". This path MUST use the "https" scheme

And it may retrieve metadata from there including "registration_endpoint"

?!

yvolk commented 1 year ago

Hi @naturzukunft I just implemented support of "OAuth 2.0 Authorization Server Metadata" (RFC 8414) So we are no longer tied to Mastodon's hardcoded OAuth endpoints. See #561

naturzukunft commented 9 months ago

@yvolk Sorry for late answer. Thank you very much for keeping me up to date! I did a lot of refactoring in rdf-pub. Since today i've again a startable docker image available. Now i have to trigger my admins to deploy it on kubernetes. After that i can finally test it.