Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latest CBL accessing /_session #41

Closed
ghost opened this issue Apr 15, 2013 · 10 comments
Closed

Latest CBL accessing /_session #41

ghost opened this issue Apr 15, 2013 · 10 comments

Comments

@ghost
Copy link

ghost commented Apr 15, 2013

I have an issue I can't get to the bottom of.

I have CBL/sync_gateway working fine, and I have Persona logon working fine, but when I try to setup CB:/sync_gateway to use Person Authentication CBL seems to be trying to access the /_session without the DB prefix.

I have updated to the latest CBL/sync_gateway 14th April, so I think this is a setup issue but I can't figure out what is causing the behaviour.

Here are some details of my setup config:

sync_gateway

In my config I have added the following to force authentication:

"users": {
"GUEST": {"disabled": true}
},

I have the following Logging enabled:

"log": ["CRUD", "REST", "REST+"],

On the sync_gateway command line I have added:

-personaOrigin "http://Macintosh-40.local:4984/"

On startup the only info in the console relating to authentication is:

Reset guest user to config

On the Client side

I initially setup a replication without authentication and I see the following in the sync_gateway console:

10:30:18.124159 Auth failed for username="", cookie=
10:30:18.124200 HTTP: --> 401 Invalid login
10:30:18.124978 Auth failed for username="", cookie=
10:30:18.125013 HTTP: --> 401 Invalid login
10:30:18.175147 HTTP: GET /mydb/_local/6a3ee783b4eb34bcba1568d3834010cc15eaf670
10:30:18.175742 Auth failed for username="", cookie=
10:30:18.175783 HTTP: --> 401 Invalid login
10:30:18.214173 HTTP: GET /mydb/_local/c0f0d4a7564c4d98e5a3d83d68d4dbc30a6a0b26
10:30:18.214554 Auth failed for username="", cookie=
10:30:18.214599 HTTP: --> 401 Invalid login

Which seems reasonable

I call the Persona login with

startBrowserIDWithOrigin:@"http://Macintosh-40.local:4984/"

Once the user logs in with Persona I setup a new db and replication with this code:

    NSArray* replsModel = [_database replicateWithURL:_syncGatewayURL exclusively: YES];


    CBLReplication *pullRepl = (CBLReplication *)[replsModel objectAtIndex:0];
    bool pullAsserted = [pullRepl registerPersonaAssertion: _assertion];

    pullRepl.filter = @"sync_gateway/bychannel";
    pullRepl.query_params = [NSDictionary dictionaryWithObjectsAndKeys:@"*",@"channels", nil];
    pullRepl.persistent = YES;
    pullRepl.continuous = YES;

    CBLReplication *pushRepl = (CBLReplication *)[replsModel objectAtIndex:1];
    bool pushAsserted = [pushRepl registerPersonaAssertion: _assertion.rawAssertion];

    pushRepl.persistent = YES;
    pushRepl.continuous = YES;

Then I see this in the client console

10:02:49.370| Sync: ReplicatorManager: Validating CBLRevision[D9AE..CEA1/]: {
"_id" = "D9AE6C7F-D4FF-4A0D-8C61-4C3669C1CEA1";
"_replication_id" = "B1E4A486-6759-4D76-B22D-C039EA1F1DD6";
"_replication_state_time" = 1365984469;
"_rev" = "5-cb9e1ddad583ab03e85e9f3445009f1f";
continuous = 1;
filter = "sync_gateway/bychannel";
"query_params" = {
channels = "*";
};
source = {
auth = {
persona = {
email = "me@example.com";
};
};
url = "http://Macintosh-40.local:4984/mydb";
};
target = "mylocaldb";
}
.
.
.
10:02:49.594| Sync: ReplicatorManager: Validating CBLRevision[2CD7..C538/]: {
"_id" = "2CD77F55-489A-4272-94D5-9E43FE1CC538";
"_replication_id" = "EC89B67F-D896-4C73-B6B7-B62F47D6350A";
"_replication_state_time" = 1365984469;
"_rev" = "5-5fd8c75769374a687925eedbef454cf5";
continuous = 1;
source = "mylocaldb";
target = {
auth = {
persona = {
email = "me@example.com";
};
};
url = "http://Macintosh-40.local:4984/mydb";
};
}
.
.
.
10:02:49.868| CBLRemoteJSONRequest[GET http://Macintosh-40.local:4984/_session]: Got error Error Domain=CBLHTTP Code=404 "404 not_found" UserInfo=0x1cd60ca0 {NSURL=http://Macintosh-40.local:4984/_session, NSLocalizedFailureReason=not_found, NSLocalizedDescription=404 not_found}
10:02:49.869| Sync: CBL_Puller[http://Macintosh-40.local:4984/mydb]: Session check failed: Error Domain=CBLHTTP Code=404 "404 not_found" UserInfo=0x1cd60ca0 {NSURL=http://Macintosh-40.local:4984/_session, NSLocalizedFailureReason=not_found, NSLocalizedDescription=404 not_found}
10:02:49.869| Sync: CBL_Puller[http://Macintosh-40.local:4984/mudb]: postProgressChanged (0/0, active=1 (batch=0, net=1), online=1)
10:02:49.870| Sync: CBL_Puller[http://Macintosh-40.local:4984/mydb]: postProgressChanged (0/0, active=0 (batch=0, net=0), online=1)
10:02:49.870| CBLRemoteJSONRequest[GET http://Macintosh-40.local:4984/_session]: Got error Error Domain=CBLHTTP Code=404 "404 not_found" UserInfo=0x1cddf8a0 {NSURL=http://Macintosh-40.local:4984/_session, NSLocalizedFailureReason=not_found, NSLocalizedDescription=404 not_found}
10:02:49.871| Sync: CBL_Pusher[http://Macintosh-40.local:4984/mydb]: Session check failed: Error Domain=CBLHTTP Code=404 "404 not_found" UserInfo=0x1cddf8a0 {NSURL=http://Macintosh-40.local:4984/_session, NSLocalizedFailureReason=not_found, NSLocalizedDescription=404 not_found}
10:02:49.872| Sync: CBL_Pusher[http://Macintosh-40.local:4984/mydb]: postProgressChanged (0/0, active=1 (batch=0, net=1), online=1)
10:02:49.872| Sync: CBL_Pusher[http://Macintosh-40.local:4984/mydb]: postProgressChanged (0/0, active=0 (batch=0, net=0), online=1)

Nothing at all is written to the sync_gateway console

I think the problem is that /_session is being called instead of /mydb/_session, but also I was not sure if _persona should be called rather than _session.

I have checked the source and it is using the ..Persona.. version of the Authorizer class, I have rebuilt the framework twice so I think I have the latest CBL framework in my project.

I suspect I have some bad config somewhere, but I have failed to find it so far.

@ghost
Copy link
Author

ghost commented Apr 15, 2013

I think this is probably related to issue #51 on sync_gateway, I have two DB's defined, everything works fine in guest mode but breaks with Persona auth on.

@ghost
Copy link
Author

ghost commented Apr 15, 2013

I'm going to close this issue and let it be handled over on the sync_gateway issue list under #51. If I have problems syncing with a single DB I'll raise a new issue here.

@ghost ghost closed this as completed Apr 15, 2013
@snej
Copy link
Contributor

snej commented Apr 15, 2013

CBL seems to be trying to access the /_session without the DB prefix.

That means you have an older version of CBL from before we moved the _persona endpoint on the server side.

@ghost
Copy link
Author

ghost commented Apr 15, 2013

Jens

Hi, I have something that claims to be a Person build, the framework header CBLReplication.h contains, I rebuilt the Framework twice as that was my first thought, I also visually checked that some of the latest mods were present.

I have moved to one DB now and I am getting a lot more traffic but still no Persona login, I'm still digging.

Andy

/** The base URL of the remote server, for use as the "origin" parameter when requesting Persona authentication. /
@Property (readonly) NSURL
personaOrigin;

/** Email address for remote login with Persona (aka BrowserID). This is stored persistently in
the replication document, but it's not sufficient for login (you also need to go through the
Persona protocol to get a signed assertion, which you then pass to the
-registerPersonaAssertion: method.)/
@Property (nonatomic, copy) NSString
personaEmailAddress;

/** Registers a Persona 'assertion' (ID verification) string that will be used on the next login to the remote server. This also sets personaEmailAddress.
Note: An assertion is a type of certificate and typically has a very short lifespan (like, a
few minutes.) For this reason it's not stored in the replication document, but instead kept
in an in-memory registry private to the Persona authorizer. You should initiate a replication
immediately after registering the assertion, so that the replicator engine can use it to
authenticate before it expires. After that, the replicator will have a login session cookie
that should last significantly longer before needing to be renewed. */

  • (bool) registerPersonaAssertion: (NSString*)assertion attribute((nonnull));

@snej
Copy link
Contributor

snej commented Apr 15, 2013

Ah, I just noticed you said _session not _persona.

Looking at the code, CBLReplicator still access /_session to check for an existing login cookie. The sync gateway handles this endpoint as long as there's only a single db; but if there are multiple dbs it doesn't, because it's ambiguous which one is meant. Thus your error.

Crap, not sure what to do about this, since the replicator does need to be compatible with CouchDB as well. Let me think...

@snej snej reopened this Apr 15, 2013
@ghost
Copy link
Author

ghost commented Apr 15, 2013

Could you provide an aggregate set of sessions on /_session (from all active DB's) assuming session ID's a GUIDS

@snej
Copy link
Contributor

snej commented Apr 15, 2013

Here's a patch that will fall back to /db/_session if /_session isn't found. Could you try it out?

diff --git a/Source/CBL_Replicator.m b/Source/CBL_Replicator.m
index d1ae714..b8f34ad 100644
--- a/Source/CBL_Replicator.m
+++ b/Source/CBL_Replicator.m
@@ -484,14 +484,22 @@ NSString* CBL_ReplicatorStoppedNotification = @"CBL_ReplicatorStopped";
         [self fetchRemoteCheckpointDoc];
         return;
     }
+    [self checkSessionAtPath: @"/_session"];
+}

+- (void) checkSessionAtPath: (NSString*)sessionPath {
     // First check whether a session exists
     [self asyncTaskStarted];
     [self sendAsyncRequest: @"GET"
-                      path: @"/_session"
+                      path: sessionPath
                       body: nil
               onCompletion: ^(id result, NSError *error) {
                   if (error) {
+                      // CouchDB has /_session, but the Sync Gateway uses /db/_session
+                      if (error.code == kCBLStatusNotFound && $equal(sessionPath, @"/_session")) {
+                          [self checkSessionAtPath: @"_session"];
+                          return;
+                      }
                       LogTo(Sync, @"%@: Session check failed: %@", self, error);
                       self.error = error;
                   } else {

@ghost
Copy link
Author

ghost commented Apr 15, 2013

Jens

I can't do a complete end-to-end test at the moment as my Persona auth is broken for one DB, but you can see the first two sync_gateway entries below indicate that the db/_session URL was called.

Once I figure out what's wrong with my Persona login I'll do a full two DB test with the patch.

21:54:06.260931 HTTP: GET /mydb/_session
21:54:06.261353 HTTP: GET /mydb/_session

@snej snej closed this as completed in 61c7917 Apr 15, 2013
@snej
Copy link
Contributor

snej commented Apr 15, 2013

OK, thanks. I'll commit the change since it does seem to have helped.

@ghost
Copy link
Author

ghost commented Apr 16, 2013

I have fixed my Persona Auth issue, I'll probably generate a pull request in the next couple of days, but it has allowed me to test against sync_gateway with two DB's and the client both authenticates with one of the two DB's and syncs with it (only push to sync_gateway covered in test).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant