|
|
|
@ -8,7 +8,7 @@
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
bool route_oauth_authorize( struct http_request* req )
|
|
|
|
|
static bool handle_oauth_authorize( struct http_request* req )
|
|
|
|
|
{
|
|
|
|
|
char* client_id = NULL;
|
|
|
|
|
char* redirect_uri = NULL;
|
|
|
|
@ -73,6 +73,11 @@ bool route_oauth_authorize( struct http_request* req )
|
|
|
|
|
result =false; goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Store the redirect URI for later use
|
|
|
|
|
free(app->redirect_uri);
|
|
|
|
|
app->redirect_uri = redirect_uri;
|
|
|
|
|
client_app_save( app );
|
|
|
|
|
|
|
|
|
|
http_request_send_headers( req, 200, "text/html", true );
|
|
|
|
|
FILE* f = http_request_get_response_body( req );
|
|
|
|
|
#define RENDER
|
|
|
|
@ -88,11 +93,10 @@ cleanup:
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool route_oauth_do_authorize( struct http_request* req )
|
|
|
|
|
static bool handle_oauth_do_authorize( struct http_request* req )
|
|
|
|
|
{
|
|
|
|
|
char* password = NULL;
|
|
|
|
|
char* state = NULL;
|
|
|
|
|
char* redirect_uri = NULL;
|
|
|
|
|
struct owner* o = owner_new();
|
|
|
|
|
struct client_app* app = NULL;
|
|
|
|
|
|
|
|
|
@ -109,8 +113,6 @@ bool route_oauth_do_authorize( struct http_request* req )
|
|
|
|
|
password = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
} else if( 0 == strcmp(key,"state") ) {
|
|
|
|
|
state = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
} else if( 0 == strcmp(key,"redirect_uri") ) {
|
|
|
|
|
redirect_uri = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
} else if( 0 == strcmp(key,"id") ) {
|
|
|
|
|
const char* client_id = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
app = client_app_from_id( client_id );
|
|
|
|
@ -134,7 +136,7 @@ bool route_oauth_do_authorize( struct http_request* req )
|
|
|
|
|
char location[512];
|
|
|
|
|
char workspace[1024];
|
|
|
|
|
const char* fmt = ( state ? "%s?code=%s&state=%s" : "%s?code=%s" );
|
|
|
|
|
snprintf( location, 512, fmt, http_escape( redirect_uri, workspace, 1024, ":/" ), app->auth_code, state );
|
|
|
|
|
snprintf( location, 512, fmt, http_escape( app->redirect_uri, workspace, 1024, ":/" ), app->auth_code, state );
|
|
|
|
|
|
|
|
|
|
printf( "redirecting to %s\n", location );
|
|
|
|
|
|
|
|
|
@ -156,13 +158,104 @@ access_denied:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool handle_oauth_get_token( struct http_request* req )
|
|
|
|
|
{
|
|
|
|
|
bool result = true;
|
|
|
|
|
char* auth_code = NULL;
|
|
|
|
|
struct client_app* app = NULL;
|
|
|
|
|
char* redirect_uri = NULL;
|
|
|
|
|
char* client_secret = NULL;
|
|
|
|
|
|
|
|
|
|
FILE* body = http_request_get_request_data(req);
|
|
|
|
|
|
|
|
|
|
struct form_parser* fp = form_pull_parser_new(body);
|
|
|
|
|
if( !fp ) {
|
|
|
|
|
goto invalid_request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* key;
|
|
|
|
|
while( key = form_pull_parser_read_key( fp ) ) {
|
|
|
|
|
if( 0 == strcmp(key,"grant_type") ) {
|
|
|
|
|
if( 0 != strcmp(form_pull_parser_read_value(fp),"authorization_code") ) {
|
|
|
|
|
goto invalid_request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"code") ) {
|
|
|
|
|
auth_code = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"client_id") ) {
|
|
|
|
|
const char* client_id = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
app = client_app_from_id( client_id );
|
|
|
|
|
if( !app ) { goto invalid_request; }
|
|
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"client_secret") ) {
|
|
|
|
|
client_secret = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"redirect_uri") ) {
|
|
|
|
|
redirect_uri = strdup(form_pull_parser_read_value(fp));
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
printf( "%s=", key );
|
|
|
|
|
printf( "%s\n", form_pull_parser_read_value(fp) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
form_pull_parser_release(fp);
|
|
|
|
|
|
|
|
|
|
if( !auth_code ) { goto invalid_request; }
|
|
|
|
|
if( !app ) { goto invalid_request; }
|
|
|
|
|
|
|
|
|
|
if( redirect_uri ) {
|
|
|
|
|
if( 0 != strcmp( app->redirect_uri, redirect_uri ) ) {
|
|
|
|
|
goto invalid_request;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( 0 != strcmp( app->auth_code, auth_code ) ) { goto access_denied; }
|
|
|
|
|
if( 0 != strcmp( app->client.secret, client_secret ) ) { goto access_denied; }
|
|
|
|
|
|
|
|
|
|
// TODO: check code has not expired
|
|
|
|
|
|
|
|
|
|
client_app_generate_access_token( app );
|
|
|
|
|
|
|
|
|
|
http_request_begin_send_headers( req, 200, false );
|
|
|
|
|
http_request_send_header( req, "Content-Type", "application/json" );
|
|
|
|
|
http_request_send_header( req, "Cache-Control", "no-store" );
|
|
|
|
|
http_request_end_send_headers( req, false );
|
|
|
|
|
|
|
|
|
|
FILE* f = http_request_get_response_body( req );
|
|
|
|
|
#define RENDER
|
|
|
|
|
#include "view/token_grant.json.inc"
|
|
|
|
|
#undef RENDER
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
if( app ) {
|
|
|
|
|
client_app_free(app);
|
|
|
|
|
}
|
|
|
|
|
free(auth_code);
|
|
|
|
|
free(client_secret);
|
|
|
|
|
free(redirect_uri);
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
access_denied:
|
|
|
|
|
result = false;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
|
|
invalid_request:
|
|
|
|
|
result = false;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool route_oauth( struct http_request* req )
|
|
|
|
|
{
|
|
|
|
|
if( http_request_route( req, "/authorize" ) ) {
|
|
|
|
|
if( http_request_route_method(req,"POST") ) {
|
|
|
|
|
return route_oauth_do_authorize(req);
|
|
|
|
|
return handle_oauth_do_authorize(req);
|
|
|
|
|
} else if( http_request_route( req, "?" ) ) {
|
|
|
|
|
return route_oauth_authorize(req);
|
|
|
|
|
return handle_oauth_authorize(req);
|
|
|
|
|
}
|
|
|
|
|
} else if( http_request_route( req, "/token" ) ) {
|
|
|
|
|
if( http_request_route_method(req,"POST") ) {
|
|
|
|
|
return handle_oauth_get_token(req);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|