Register new memer for vBulletin via Mobile API - vbulletin

I'm trying to use the vBulletin REST Mobile API to simply register.
The sourced are installed on my local machine and according the documentation https://www.vbulletin.com/forum/content.php/393-User-Registration-Process-Mobile-API
This procedure should not be so hard, especially without humanity and COPPA authentication.
However I've stacked!
The method definition describes "addnewmember" clear, so I've generated a test link, which should do the job.
https://www.vbulletin.com/forum/content.php/365-User-Related-Methods
The link is:
.../forum/api.php?&api_m=register_addmember&api_c=1&api_s=76ec9eec61e7fdfef2f3feee28d5f392&api_sig=8fe54313b333cc0fef4ddd8e398b5c80&api_v=6&agree=1&username=testuser&email=XXXXXX%40gmail.com&emailconfirm=XXXXX%40gmail.com&password=12345678&passwordconfirm=12345678
As a response I get: register_not_agreed
The Docs: register_not_agreed
The agree parameter should be set to 1.
Which is also clear - agree parameter was not there.
Here comes the funny part - In the API-Log I can see that the 'agree' parameter is correctly passed
*1 test_client Gast 13:23, 18.06.2012 register_addmember Array ( [api_m] => register_addmember [api_c] => 1 [api_s] => 76ec9eec61e7fdfef2f3feee28d5f392 [api_sig] => 8fe54313b333cc0fef4ddd8e398b5c80 [api_v] => 6 [agree] => 1 [username] => testuser [email] => ....*
Is there anybody with experience with the Mobile API that could help?

I don't know why it does not work with a pure GET call but I'm sure it will work (because I'm working on a vBulletin API client in Python and I did it this way) if you:
use GET parameters to send api_c, api_sm, api_m, and api_sig
use POST data for all the rest (username, email, agree, etc)

Related

Looking for a start-to-finish how-to on Laravel 5.2 OAuth2 implementation

Quick background: I'm fairly experienced with PHP, but needed to build my first RESTful API. I figured I'd try Laravel (5.2) and am starting to feel pretty comfortable with it.
I started adding auth to my project over the weekend and I am really struggling to get it working. I got the basic Laravel Auth middleware working quickly, but I think I need to be using OAuth2 for production (I will be building a mobile app that will connect up to this server). I'm using the Luca Degasperi OAuth2 package, which seems to be pretty popular.
I reviewed the actual documentation: https://github.com/lucadegasperi/oauth2-server-laravel/tree/master/docs#readme)
I also went through this tutorial: https://medium.com/#mshanak/laravel-5-token-based-authentication-ae258c12cfea#.5lszb67xb
And, most recently, I found this thread about the need to seed the OAuth tables before anything will work: https://github.com/lucadegasperi/oauth2-server-laravel/issues/56
That's all great, but there are some minor differences in the most recent distribution of Laravel. For example, /app/Http/Kernel.php is slightly different from what's shown in some of the examples I found because it now uses middleware groups. I thought I handled those differences correctly (I added the OAuthExceptionHandlerMiddleware class to the 'web' section of $middlewareGroups instead of $middleware). I got my seeder working (the current oauth_scopes table only allows you to supply a description, so I had to slim down what was provided in the third link above).
If I put a test route in my 'web' group in routes.php, I would have thought this would require OAuth because I added OAuth to the 'web' middleware group in Kernel.php. That's not the case. My route works with no authentication if I do that.
I then explicitly added the OAuth middleware to my test route as follows:
Route::get('tests/events', ['middleware' => 'oauth', function() {
$events = App\Event::get();
return response()->json($events);
}]);
That causes a 500 error ("ErrorException in OAuth2ServerServiceProvider.php line 126: explode() expects parameter 2 to be string, object given").
I'm to feel pretty lost. Each of these packages seems to be shifting so quickly that there's no complete documentation on how to get this up and running.
What else do I need to do to get this functioning?
The following link is what finally got me un-stuck:
https://github.com/lucadegasperi/oauth2-server-laravel/blob/master/docs/authorization-server/password.md
Now that I have it working, I'll try and make this a complete how-to FOR PASSWORD GRANT TYPES ONLY. I didn't play with other grant types. So this assumes you're building something like a RESTful API where users will connect to it with a client app that you're going to build. So users will create a user account in your system and then when they send a REST request, the OAuth2 package will authenticate them and send them a token to stay logged in.
I'm using Laravel 5.2 and already had the basic Auth package up and running. Be advised that a lot of these steps seem to change even with incremental releases of Laravel or the OAuth2 package.
The first part of getting this working is fairly well documented already (https://github.com/lucadegasperi/oauth2-server-laravel/tree/master/docs#readme), but here's a summary just in case...
Edit the require section of your composer.json file to look something like this:
"require": {
"php": ">=5.5.9",
"laravel/framework": "5.2.*",
"lucadegasperi/oauth2-server-laravel": "5.1.*"
},
Run composer update to download the package.
Open your config/app.php file and add the following two lines to the end of the providers section:
LucaDegasperi\OAuth2Server\Storage\FluentStorageServiceProvider::class,
LucaDegasperi\OAuth2Server\OAuth2ServerServiceProvider::class,
Also in config/app.php, add this line to the aliases array:
'Authorizer' => LucaDegasperi\OAuth2Server\Facades\Authorizer::class,
Now we start to do things a little differently from the documentation to accommodate the current version of Laravel...
Open app/Http/Kernel.php. Laravel now uses groups and it didn't used to. Update your $middlewareGroups to look like this:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
//Added for OAuth2 Server
\LucaDegasperi\OAuth2Server\Middleware\OAuthExceptionHandlerMiddleware::class,
//Commented out for OAuth2 Server
//\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
Also in app/Http/kernel.php, update $routeMiddleware to look like this:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
//Added for OAuth2 Server
'oauth' => \LucaDegasperi\OAuth2Server\Middleware\OAuthMiddleware::class,
'oauth-user' => \LucaDegasperi\OAuth2Server\Middleware\OAuthUserOwnerMiddleware::class,
'oauth-client' => \LucaDegasperi\OAuth2Server\Middleware\OAuthClientOwnerMiddleware::class,
'check-authorization-params' => \LucaDegasperi\OAuth2Server\Middleware\CheckAuthCodeRequestMiddleware::class,
'csrf' => App\Http\Middleware\VerifyCsrfToken::class,
];
You now have to set up your grant types. You used to do this all in one place in config\oauth2.php using an array with a closure for callback. With the most recent version of the OAuth2 server package, you can't use a closure for callback anymore. It has to be a string. So your grant_types should look something like this:
'grant_types' => [
'password' => [
'class' => '\League\OAuth2\Server\Grant\PasswordGrant',
'callback' => '\App\PasswordGrantVerifier#verify',
'access_token_ttl' => 3600
]
]
access_token_ttl is the duration that an auth token will be good for (in seconds). The main package documentation uses 3600 (1 hour) by default. You might want to try 604800 (1 week) instead -- at least during testing.
You now need to create the PasswordGrantVerifier class and verify method that you just called in the code section above. So you create a file App/PasswordGrantVerifier.php and use the following code (which is basically what used to go in the closure for callback).
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
class PasswordGrantVerifier
{
public function verify($username, $password)
{
$credentials = [
'email' => $username,
'password' => $password,
];
if (Auth::once($credentials)) {
return Auth::user()->id;
}
return false;
}
}
You will need at least one row in the oauth_clients table before OAuth2 will work. You can insert something manually or create a seeder. To create a seeder, modify database/seeds/DatabaseSeeder.php and add the following to the end of the run() method:
$this->call(OAuthClientsTableSeeder::class);
Now create a file called database/seeds/OAuthClientsTableSeeder.php and enter something like this:
<?php
use Illuminate\Database\Seeder;
class OAuthClientsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
//Add sample users
$oAuthClients = array(
array(
'id' => 'TEST_ENVIRONMENT',
'secret' => 'b17b0ec30dbb6e1726a17972afad008be6a3e4a5',
'name' => 'TEST_ENVIRONMENT'
)
);
foreach ($oAuthClients as $oAuthClient) {
App\OAuthClient::create($oAuthClient);
}
}
}
Run php artisan vendor:publish to publish the package configuration and migrations. Run php artisan migrate to set up the billion-or-so new tables for OAuth. Run php artisan db:seed to seed your database.
You can now set up some test routes in app\Http\routes.php. They should look something like this:
Route::post('oauth/access_token', function() {
return Response::json(Authorizer::issueAccessToken());
});
Route::group(['middleware' => 'oauth'], function () {
Route::get('authroute', function() {
//OAuth will be required to access this route
});
Route::post('postwithauth', function(Request $request) {
$userID = Authorizer::getResourceOwnerId();
$input = $request->input();
return response()->json(array('userID' => $userID, 'input' => $input));
});
});
Route::get('noauthroute', function () {
//No authorization will be required to access this route
});
Pay close attention to the postwithauth route I included above. The OAuth2 package recently changed how you access the user's ID and it took me quite a while to figure out how to get it.
Now that it's time for testing, point your browser to localhost:8000 (or whatever the path is for your test environment) and create a user account for yourself (this step just uses the standard Laravel Auth package).
Go into your HTTP client (I'm currently using Paw and I like it). Go to request->authorization->OAuth2 to set up authorization for the route you're going to test. For Grant Type, select Resource Owner Password Credentials. If you used the seed example I provided above, the Client ID is TEST_ENVIRONMENT, the Client Secret is b17b0ec30dbb6e1726a17972afad008be6a3e4a5, enter the username (email) and password you created through the web Auth interface, your Access Toekn URL will be something like localhost:8000/oauth/access_token (depending on how you set up your test environment), leave Scope blank, and Token should say Bearer. Click on Get Access Token then say Use Access Token when prompted.
That should be it!

GraphMethodException - Unsupported get request at

I have two Debian-systems. With both I access the Facebook-API via Perl(Facebook::Graph).
On the first system this works perfectly, on the other system I ran into following problem.
Could not execute request (https://graph.facebook.com): GraphMethodException - Unsupported get request at /usr/local/share/perl/5.10.1/Facebook/Graph/Response.pm line 40
Response.pm:
[...]
has response => (
is => 'rw',
isa => 'HTTP::Response',
required=> 1,
);
[...]
ouch $response->code, 'Could not execute request ('.$response->request->uri->as_string.'): '.$message, $response->request->uri->as_string;
[...]
I know it has something to do with my ssl-libs, but I cannot figure out where the problem is. I reinstalled multiple times the IO:Socket:SSL and SSLeay.
Every help is welcome,
enzo
Don't know if this helps, but came on here looking for help with 'graphMethodException' when trying to access this page: http://graph.facebook.com/doodleembroidery (which works fine now).
Have just tracked it down to the page's country permissions. She didn't realise she had set restrictions when she created the page, now she's removed them the link works fine!

Testing a JSON PUT request in mojolicious

I am creating test cases for my app developed using Mojolicious framework. I am testing the routes for appropriate responses for the REST calls that are made. I use JSON as a means of communication between the server and client. To test GET, POST and DELETE requests I use the following functions
GET : get_ok()POST: post_json_ok() DELETE: delete_ok()
but for PUT I am not able to use put_ok(). And example of my usage of put_ok() would be my $t = Test::Mojo->new;$t->put_ok('this/is/url/to/resource'=>{ "element" => "modified value"})->status_is(204)
I get a bad request status every time(400) and so the test fails. I use Test::Mojo for testing my application.
Additional information:
$t->put_ok('http://localhost:3000/application/instances/system/test'=>{"model" => "testing put"})->status_is(204);
This is the exact test for PUT request that is attempted. model is a property of resource test that is being attempted to be changed to testing put and the expected status response is 204.
The mapping to the controller is done by
$r->route('/application/instances/system/:id, id => qr/[A-Za-z0-9 ]+/ -> via('put')
->to(controller => 'system', action => 'update_sys');
This route calls the update_sys method in the system controller and that is how the resource is located.
Actually, after discussions with SRI on IRC, he pointed me to an example almost identical you your needs in the documentation.
# Test custom transaction
my $tx = $t->ua->build_json_tx('/user/99' => {name => 'sri'});
$tx->req->method('PUT');
$t->tx($t->ua->start($tx))
->status_is(200)
->json_is('/message' => 'User has been replaced.');
So this should work for you!
Postscript:
You might be interested to know that this discussion has brought some progress: the next release of Mojolicious (version 3.66) will now have a cleaner syntax for this purpose, the new request_ok method. The above example can then be rewritten as
my $tx = $t->ua->build_json_tx('/user/99' => {name => 'sri'});
$tx->req->method('PUT');
$t->request_ok($tx)
->status_is(200)
->json_is('/message' => 'User has been replaced.');
Can you share the definition of your route for 'this/is/url/to/resource' ? the server is returning 400, so it appears Mojo::Controller in your app does not understand what you are sending ...

Asterisk : originate call doesn't set the CALLERID in the dialplan

I am using Asterisk PBX to call a softphone, i use thise command : "originate SIP/100 extension 4004" , in the dialplan, I have to get the CALLERID variable, but in this case, it's always empty!
P.S : if i call the extension (4004), from the softphone(100), the CALLERID is set, and I can get it with : ${CALLERID(num)}.
How to get the caller id in the originate case?
When you're originating a call, you set the Caller ID yourself. There are two ways of doing this - either in the originate application yourself, or in the dialplan. An example of this is below.
Action: Originate
Channel: local/12345#outgoing
Application: Echo
CallerID: Asterisk <12345>
extensions.conf:
[outgoing]
exten => 12345,1,NoOp()
same => n,Verbose(1, Outgoing Caller ID: {$CALLERID(all)})
same => n,Dial(SIP/${EXTEN})
same => n,Hangup()
or you could do something like:
exten => 12345,1,NoOp()
same => n,Set(CALLERID(num)=54321)
same => n,Set(CALLERID(name)=Asterisk)
same => n,Verbose(1, Outgoing Caller ID: {$CALLERID(all)})
same => n,Dial(SIP/${EXTEN})
same => n,Hangup()
You should see your caller ID set either in the AMI originate or, if you choose to override it in the dialplan, those values.
For more information, see Manager Action Originate and CallerID Function.
I know this is way late but if your on Asterisk 1.8 the Originate app just does not allow it normally.
I had asked in the forums before and they said that feature would be added at a later point. So what I did was modify the app_originate.c to allow number and name to be passed.
Here is the one I wrote up last year:
https://github.com/cmendes0101/asterisk-originate-callerid
Been in production for over a year and has been working good. Was written for 1.8. It was a easy modification so if your using a different version you can simple diff the changes and make those small changes to your version to make it happen.
the final solution i am using now :
i call my extention from a php script (originate SIP/100 extension 777)
i write my extension to a text file (file_put_contents)
then i read it in the asterisk dial plan, and set this variable as the caller ID Set(CALLERID(num)=${caller_id}
i didn't find another solution.

How do I use and debug WWW::Mechanize?

I am very new to Perl and i am learning on the fly while i try to automate some projects for work. So far its has been a lot of fun.
I am working on generating a report for a customer. I can get this report from a web page i can access.
First i will need to fill a form with my user name, password and choose a server from a drop down list, and log in.
Second i need to click a link for the report section.
Third a need to fill a form to create the report.
Here is what i wrote so far:
my $mech = WWW::Mechanize->new();
my $url = 'http://X.X.X.X/Console/login/login.aspx';
$mech->get( $url );
$mech->submit_form(
form_number => 1,
fields =>{
'ctl00$ctl00$cphVeriCentre$cphLogin$txtUser' => 'someone',
'ctl00$ctl00$cphVeriCentre$cphLogin$txtPW' => '12345',
'ctl00$ctl00$cphVeriCentre$cphLogin$ddlServers' => 'Live',
button => 'Sign-In'
},
);
die unless ($mech->success);
$mech->dump_forms();
I dont understand why, but, after this i look at the what dump outputs and i see the code for the first login page, while i belive i should have reached the next page after my successful login.
Could there be something with a cookie that can effect me and the login attempt?
Anythings else i am doing wrong?
Appreciate you help,
Yaniv
This is several months after the fact, but I resolved the same issue based on a similar questions I asked. See Is it possible to automate postback from the client side? for more info.
I used Python's Mechanize instead or Perl, but the same principle applies.
Summarizing my earlier response:
ASP.NET pages need a hidden parameter called __EVENTTARGET in the form, which won't exist when you use mechanize normally.
When visited by a normal user, there is a __doPostBack('foo') function on these pages that gives the relevant value to __EVENTTARGET via a javascript onclick event on each of the links, but since mechanize doesn't use javascript you'll need to set these values yourself.
The python solution is below, but it shouldn't be too tough to adapt it to perl.
def add_event_target(form, target):
#Creates a new __EVENTTARGET control and adds the value specified
#.NET doesn't generate this in mechanize for some reason -- suspect maybe is
#normally generated by javascript or some useragent thing?
form.new_control('hidden','__EVENTTARGET',attrs = dict(name='__EVENTTARGET'))
form.set_all_readonly(False)
form["__EVENTTARGET"] = target
You can only mechanize stuff that you know. Before you write any more code, I suggest you use a tool like Firebug and inspect what is happening in your browser when you do this manually.
Of course there might be cookies that are used. Or maybe your forgot a hidden form parameter? Only you can tell.
EDIT:
WWW::Mechanize should take care of cookies without any further intervention.
You should always check whether the methods you called were successful. Does the first get() work?
It might be useful to take a look at the server logs to see what is actually requested and what HTTP status code is sent as a response.
If you are on Windows, use Fiddler to see what data is being sent when you perform this process manually, and then use Fiddler to compare it to the data captured when performed by your script.
In my experience, a web debugging proxy like Fiddler is more useful than Firebug when inspecting form posts.
I have found it very helpful to use Wireshark utility when writing web automation with WWW::Mechanize. It will help you in few ways:
Enable you realize whether your HTTP request was successful or not.
See the reason of failure on HTTP level.
Trace the exact data which you pass to the server and see what you receive back.
Just set an HTTP filter for the network traffic and start your Perl script.
The very short gist of aspx pages it that they hold all of the local session information within a couple of variables prefixed by "__" in the general aspxform. Usually this is a top level form and all form elements will be part of it, but I guess that can vary by implementation.
For the particular implementation I was dealing with I needed to worry about 2 of these state variables, specifically:
__VIEWSTATE
__EVENTVALIDATION.
Your goal is to make sure that these variables are submitted into the form you are submitting, since they might be part of that main form aspxform that I mentioned above, and you are probably submitting a different form than that.
When a browser loads up an aspx page a piece of javascript passes this session information along within the asp server/client interaction, but of course we don't have that luxury with perl mechanize, so you will need to manually post these yourself by adding the elements to the current form using mechanize.
In the case that I just solved I basically did this:
my $browser = WWW::Mechanize->new( );
# fetch the login page to get the initial session variables
my $login_page = 'http://www.example.com/login.aspx';
$response = $browser->get( $login_page);
# very short way to find the fields so you can add them to your post
$viewstate = ($browser->find_all_inputs( type => 'hidden', name => '__VIEWSTATE' ))[0]->value;
$validation = ($browser->find_all_inputs( type => 'hidden', name => '__EVENTVALIDATION' ))[0]->value;
# post back the formdata you need along with the session variables
$browser->post( $login_page, [ username => 'user', password => 'password, __VIEWSTATE => $viewstate, __EVENTVALIDATION => $validation ]);
# finally get back the content and make sure it looks right
print $response->content();