spring-attic / spring-social

Allows you to connect your applications with SaaS providers such as Facebook and Twitter.
http://projects.spring.io/spring-social
Apache License 2.0
619 stars 351 forks source link

[suggestion] Halting Connection process by returning boolean from preConnect? #26

Closed rickcr closed 12 years ago

rickcr commented 12 years ago

In our application we do not want to allow a user to connect with a different facebook connection if they've already connected previously with a different facebook providerUserId.

I've already had to extend ConnectController for some other purposes so I could accomplish what I need by overriding connect as so:


@Override
public RedirectView connect(@PathVariable String providerId, NativeWebRequest request) {
    /*
    User from session
    if userId found in UserConnections table for the providerId, then abort the connect process
    put message in scope "This account has already been connected with Facebook User: "John Doe"
    return user to some page
    */
    else {
        return super.connect(providerId, request);
    } 
}

However, many users might not have a need to really extend ConnectController but they'll probably have created an Interceptor and might be relying on preConnect.

I was thinking why not have preConnect in ConnectController return a boolean and in the preConnect method if any of the interceptor preConnects return a 'false' then you leave preConnect and return false. Within "connect" you'd then halt the oauth stuff if preConnect returned false. So something like:

@RequestMapping(value="/{providerId}", method=RequestMethod.POST)
public RedirectView connect(@PathVariable String providerId, NativeWebRequest request) {
    ConnectionFactory<?> connectionFactory = connectionFactoryLocator.getConnectionFactory(providerId);
    MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>(); 
    if (preConnect(connectionFactory, parameters, request)) {
            return new RedirectView(webSupport.buildOAuthUrl(connectionFactory, request, parameters));
    } else {
        return new RedirectView("connectionExistsForUser");
    }
}

@SuppressWarnings({ "rawtypes", "unchecked" })
protected boolean preConnect(ConnectionFactory<?> connectionFactory, MultiValueMap<String, String> parameters, WebRequest request) {
    for (ConnectInterceptor interceptor : interceptingConnectionsTo(connectionFactory)) {
        boolean ok = interceptor.preConnect(connectionFactory, parameters, request);
        if (!ok) return false;
    }
    return true;
}
rickcr commented 12 years ago

Actually this scenario is very unlikely to occur since you wouldn't be showing the connect button for a user who is logged in and already has an account.

In my case I need to handle my check for the user being already tied to a facebook account at a different spot - for the case where they are doing a "sign in and connect" all in one shot... which happens if they try to a signin with facebook but a different facebook account is present (for example their spouse was on the computer) - in this case I prompt them with the join form but also a "Already a member? sign and connect" - at which point I need to do a check if that member already has a facebook account tied to their account.

I'll close this since probably not worth the hassle of implementing at this point (although in general I like interceptors that can abort the process if they return false so might be something to consider in the future.)

kushalkantgoyal commented 7 years ago

I'm also facing the same thing. I don't want the user to connect a facebook or twitter account which is already connected to some other user.