/admin/users/sync_sso ... Route not found


#1

Any idea why I’m getting this when trying to issue a POST request?

ActionController::RoutingError (No route matches [POST] “/admin/users/sync_sso”)

Thanks!


(Rafael dos Santos Silva) #2

Well the route is that one.

Are you passing api_username and api_key as query params too?


#3

I am. Here is the code block. This is the exact say thing I’m doing in my SSO login route. Only difference is obviously the URI.

     const sso = new DiscourseSSO(SSOKey);
            const nonce = 'dummy data';
            const userparams = {
              nonce,
              external_id: user._id.toString(),
              email: user.email,
              username: user.username.replace(/\s/g, ''),
            };
            console.log(userparams);
            const q = sso.buildLoginString(userparams);
            fetch('https://community.testsite.com/admin/users/sync_sso', { method: 'POST', body: q })
              .then(res => res.json())
              .then(json => console.log(json));

(Rafael dos Santos Silva) #4

You aren’t passing api_username and api_key.

You need those as query params.

You can check our #howto in the topic here: Sync SSO user data with the sync_sso route


#6

sso.buildLoginString is doing that.

discourse_sso.prototype.buildLoginString = function(params) {
	if(!("external_id" in params)) {
		throw new Exception("Missing required parameter 'external_id'");
	}
	if(!("nonce" in params)) {
		throw new Exception("Missing required parameter 'nonce'");
	}
	if(!("email" in params)) {
		throw new Exception("Missing required parameter 'email'");
	}
	
	var payload = new Buffer( querystring.stringify(params) , 'utf8').toString("base64");
	var hmac = this.getHmac();
	hmac.update(payload);
	
	return querystring.stringify({
		'sso': payload,
		'sig': hmac.digest('hex')
	});

Using this node package for SSO login. Which works perfectly. Trying to repurpose that for this …


(Rafael dos Santos Silva) #7

Where? I don’t see api_username and api_key anywhere.


#8

Right. I was adding in as form data before. Here is the updated. Still getting the Route Not Found error in the rails logs though.

 const userparams = {
          nonce,
          api_username: someusername,
          api_key: somekey,
          external_id: user._id.toString(),
          email: user.email,
          username: user.username.replace(/\s/g, ''),
        };

#9

Code that produces the bottom query:

const userparams = {
      external_id: user._id.toString(),
      email: user.email,
      username: user.username.replace(/\s/g, ''),
    };
    const payload = new Buffer(querystring.stringify(userparams), 'utf8').toString('base64');
    const hmac = crypto.createHmac('sha256', DiscourseSSOKey);
    hmac.update(payload);
    const query = querystring.stringify({
      sso: payload,
      sig: hmac.digest('hex'),
      api_username: UserName,
      api_key: API Key,
    });
    console.log(query);
    fetch('https://community.somesite.com/admin/users/sync_sso', {
      method: 'POST',
      body: query,
    })
      .then(res => res.json())
      .then(json => console.log(json));    

Here’s the query that gets generated and passed as the body on the POST route:

sso=somelongSSOgenerated.&sig=somelongsignature&api_username=someusername&api_key=someAPIKey

This all still gives me a Route Not Found error in the rails logs.


#10

Any thoughts on the above? Does that look right?


(Kane York) #11

You’re delivering the wrong Content-Type. Try providing the object directly as the body to fetch, without querystring.stringify.

also, hang on a sec, i’m going to let you finish, but URLSearchParams is the best browser api of 2016


(Michael Brown) #12

The api_* parameters need to be in the query parameters, not the POST body.

So you need something like:

fetch('https://community.testsite.com/admin/users/sync_sso?api_username=USERNAME&api_key=KITTENS', { method: 'POST', body: body })

#13

Ah understood. So the api_username and api_key in the query parameters and the rest in the post body.


(Blake Erickson) #14

They can also be in the body

All my Postman requests have them in the body:

Unless this route is special?


(Simon Cossar) #15

It’s not. The WordPress plugin sends the api parameters for the sync_sso route in the body of the request: wp-discourse/discourse-sso.php at master · discourse/wp-discourse · GitHub


(Kane York) #16

That’s correct, the problem was sending the wrong body type so the api_username/api_key couldn’t be parsed out.