How use session authentication in drupal Services module - drupal

I have Drupal 7 and Services 3.x (3.10).
In the /admin/structure/services page, i have create an endpoint and my custom module:
function webServices_services_resources() {
$api = array(
'customers' => array(
'retrieve' => array(
'help' => 'Retrieves posted blogs',
'callback' => '_webServices_retrieve',
'access arguments' => array('access content'),
'access arguments append' => FALSE,
'args' => array(
array(
'name' => 'id',
'type' => 'int',
'description' => 'The id of the note to get',
'source' => array('path' => '0'),
'optional' => FALSE,
),
),
),
),
);
return $api;
}
Now i make a POST request to my base_url/endpoint/user/login.json (passing username and password) and i get the session_name and session_id.
if i call (for example) base_url/endpoint/customers/1.json with the following header:
User-Agent: Fiddler
Content-Type: application/json
Host: liburna3.alpha-si.org
Cookie: SESS738851ba4e98ab1f17a7252513dc0719=hy5xVjlDzjIbXz-nlwEV4GywbAPAPL0d_aFGhtIRWzw
i get error 403: Access denied for user xxxxxxxxx
What is the problem?

I would check my authentication state calling base_url/endpoint/system/connect.
If you are not logged in (or you header is not right) it returns:
"sessid": "PfG79I6elMMYln8nyftReLOY0d5So7O0C3LRIdbOeMo",
"session_name": "SESS74282c529439441e18b575b0e6fe308f",
"user": {
"uid": 0,
"hostname": "2a02:8388:1580:2500:7b:3322:23a4:c902",
"roles": {
"1": "anonymous user"
},
"cache": 0,
"timestamp": 1460891635
}
}
If you are logged in it returns the full userdatat in user property of result.
I setup a testing site for nearly all drupal services calls .>You can enter basepath and endpoint and test you backend.
Find it here => http://www.drupalionic.org/explore/
Enter you data and then go to Resources -> Services 3.x -> System and click the Connect tab.
You can also find a fully featured angular lib for drupal services here => https://github.com/BioPhoton/ng-drupal-7-services

Related

WordPress REST API validation always considers arrays to be empty

'methods' => ['POST', 'GET'],
'args' =>
[
'users' =>
[
'type' => 'array',
'minItems' => 1,
'items' =>
[
'type' => 'object',
'properties' =>
[
'user_login' =>
[
'type' => 'string',
'required' => true,
'validate_callback' => function($user_login)
{
error_log("login validation");
}
],
'user_email' =>
[
'type' => 'string',
'required' => false,
'validate_callback' => function($user_email)
{
error_log("email validation");
}
]
]
]
]
],
'callback' => function($request)
{
return $request->get_body_params();
}
]
As is, every request fails, saying that the users array is empty. ~~If I comment out the```minItems` line, the request succeeds and I can get the parameters in the callback; however, neither error log fires, so I can't validate the incoming data. I suspect that the main issue is whatever is causing the minItems to fail, as the API for some reason thinks there's no data, and thus nothing to validate, until the main callback fires.~~
Edit: minItems now works. The problem is otherwise the same: the args are treated as empty until the main callback fires, at which point they're populated correctly.
Validation callbacks can only be added to top-level args, not items of arrays or properties of objects. I'm going to make a feature request; I'll try to remember to update this post if it gets approved.

Dynamic query string params in Wordpress Rest API

I cant find any information in the Wordpress rest api documentation about how to pass in a dynamic string as part of a url, I know how to do an ID.
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<type>)', [
'args' => [
'type' => [
'description' => __('Type of notification to generate', $this->pluginName),
'type' => 'string',
'enum' => ['product_question']
]
],
[
'methods' => \WP_REST_Server::CREATABLE,
'callback' => [$this, 'create_item'],
'permission_callback' => [$this, 'create_item_permissions_check'],
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
],
'schema' => [$this, 'get_public_item_schema']
]);
The above is the code im using to try and register the route. The route should look something like this /notifications/product_question The last part of the url, would be the dynamic part, and would be one of an array of values

LinkedIn API Publish on network (S_412_PRECONDITION_FAILED=Invalid arguments)

When I try to publish a link on my own LinkedIn profile via the LinkedIn API, I get this error:
LinkedIn return error
Request Error: Invalid arguments: {S_412_PRECONDITION_FAILED=Invalid arguments}
My request:
$li = new LinkedIn([
'api_key' => env('LINKEDIN_KEY'),
'api_secret' => env('LINKEDIN_SECRET'),
'callback_url' => env('LINKEDIN_REDIRECT_URI')
]);
$li->setAccessToken('my_token');
return $li->post('/people/~/shares', [
'content' => [
'title' => 'This is an example of title',
'description' => 'This is a text with less 256 caracters.',
'submitted-url' => 'https://www.google.fr/',
],
'comment' => 'This is comment with less 700 caracters.',
'visibility' => [
'code' => 'anyone'
]
]);
I use the official API of LinkedIn (linkedinapi/linkedin).

405 on options when implementing security

I'm implementing security on my API and I found a road block. I'm using angular, so if the API is on a different host than the client, the client will do a OPTIONS before any POST or put.
This is my code:
$app['security.firewalls'] = array(
'v3' => array(
'pattern' => '/v3/.*', //protect /v3/ endpoints
'oauth' => true, //using oauth service
'stateless' => true, //Do not persist this token
),
'default' => [
'anonymous' => true,
'security' => false,
],
);
//We finally register our security using the silex security servide provider
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => $app['security.firewalls']
));
It works perfect for GET, POST, PUT and DELETE...It don't work for OPTIONS

Accessing app.user in unsecured area, silex

I have this configuration for firewall :
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'admin' => array(
'pattern' => '^/admin',
'form' => array(
'login_path' => '/#login',
'check_path' => '/admin/login_check',
),
'logout' => array(
'logout_path' => '/admin/logout',
)
),
'unsecured' => array(
'anonymous' => true,
'pattern' => '^.*$',
),
));
and also this for security.rules :
$app['security.access_rules'] = array(
array('^/admin', 'ROLE_ADMIN'),
array('.*', 'IS_AUTHENTICATED_ANONYMOUSLY'),
);
I see this answer : Silex/Symfony Security Firewall Access user token outside the secured area
But the problem is, I can not access the app.user in "/" page and is_granted (in twig) always return false to any input.
I don't know if the ACL mentioned in that answer is something else (other than the access_rules) or I do something wrong.
I believe a user (token) is only accessible within the firewall that logged it in. So as long as you are within /admin part of your site you would have access to the app.user, but not within the "unsecured" firewall.
To have the behaviour you are looking for, you need to have one overall/sitewide firewall with the pattern of ^/ and then use access rules to restrict access to /admin.
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'main' => array(
'pattern' => '^/',
'anonymous' => true,
'form' => array(
'login_path' => '/#login',
'check_path' => '/admin/login_check',
),
'logout' => array(
'logout_path' => '/admin/logout',
)
),
));
$app['security.access_rules'] = array(
array('^/admin', 'ROLE_ADMIN'),
array('^/', 'IS_AUTHENTICATED_ANONYMOUSLY'),
);
So a brand new user to your site would be immediately authenticated anonymously, until they login with a role that allows them to access /admin.
It's also worth noting that if you were to have your login form within admin area, as something like /admin/login. Them you would need to add an anonymous access rule for the login URL.
Hope this helps!

Resources