Is there a way to retrieve GDPR consent string from <amp-consent> within an <amp-iframe>? - gdprconsentform

I tried to retrieve the GDPR consent string using postMessage inside an amp-iframe element but it simply doesn't work.
Is there a way to communicate with the CMP inside the amp-consent and amp-iframe ?
Thx

Yes:
amp-consent caches and passes consent information to vendors via consentMetadata objects as well as a non-empty consentString. You can find and example of the consentMetadata object and its supported fields below.
{
"consentStringType": {enum} [1: TCF V1, 2: TCF V2, 3: US Privacy String] (optional),
"gdprApplies": {boolean} (optional),
"additionalConsent": {string} (optional)
}
(from: https://github.com/ampproject/amphtml/blob/master/extensions/amp-consent/integrating-consent.md#consentmetadata)

Related

Loopback 4: Authorization decoration of CRUDRestController - is it in anyway possible?

Wondering if anybody in the community has any experience or guidance on how one could use
Authorization decorators (or any custom decoration?)(https://loopback.io/doc/en/lb4/Decorators_authorize.html) on CrudRestController endpoints? (https://loopback.io/doc/en/lb4/Creating-crud-rest-apis.html).
Looked at the src for crud-rest.controller.ts and it just seems like there is no way to really do it.
It seems like it's not easily possible to use any decoration of endpoints in a CrudRestController without taking a very hacky approach and/or wholesale duplicating the code in crud-rest.controller.ts and that we'll have to basically write every endpoint for every model by hand.
Maybe someone has come up with something or has some guidance on an approach? Is the only way to use auth with CrudRestController with the AuthorizationComponent as of now to use Authorizer functions (https://loopback.io/doc/en/lb4/Authorization-component-authorizer.html)
Seems like one part lies in this :
https://github.com/loopbackio/loopback4-example-shopping/blob/9188104c01516a5cbd4ce13f28abe18bafef821e/packages/shopping/src/services/basic.authorizor.ts
/**
* Allow access only to model owners, using route as source of truth
*
* eg. #post('/users/{userId}/orders', ...) returns `userId` as args[0]
*/
if (currentUser[securityId] === authorizationCtx.invocationContext.args[0]) {
return AuthorizationDecision.ALLOW;
}
So I ended up doing :
async authorize(
context: AuthorizationContext,
metadata: AuthorizationMetadata,
) {
const parent = context.invocationContext?.parent
const request = parent?.getBinding("rest.http.request").getValue(parent)
const givenUserId = request?.body?.userId
// next line finds out the user id in the JWT payload
const jwtUserId = context?.principals[0]?.payload?.sub
if (!jwtUserId || (givenUserId && givenUserId != jwtUserId)) {
return AuthorizationDecision.DENY;
} else {
return AuthorizationDecision.ALLOW;
}
}
as my userId is provided in the http parameters (post form or get parameters)
I also use a custom JTWService to read the payload and make it available in the UserProfile.
This may not be the best way to do it, but so far it works. I am still working on finding out how to deal with read requests and add a filter on all of them by userId too using decorators I will post my finding here, if nothing better show up first here.

Api Platform pagination custom page_parameter_name

I have very specific question on which I cannot find any answer and/or solution provided for Api Platform.
By default, the documentation states, that if you want to pass a page parameter for paging action, you must do the following:
pagination:
page_parameter_name: _page
However, due to the nature of our frontend we're not able to pass this variable to the request. It is hardcoded to the frontend request and is something like page[number]=1.
Is it possible to configure page_parameter_name to receive this variable or we need to transform it somehow in the Api itself?
Thank you!
ApiPlatform\Core\EventListener\ReadListener::onKernelRequest gets $context['filters'] from the request through ApiPlatform\Core\Util\RequestParser::parseRequestParams which ultimately uses PHP's parse_str function so the value of 'page[number]' will be in $context$context['filters']['page']['number'].
ApiPlatform\Core\DataProvider\Pagination::getPage retrieves the page number from $context['filters'][$parameterName] so whatever the value of [$parameterName] it will at best retrieve the array ['number'=> 1].
Then ::getPage casts that to int, which happens to be 1. But will (at least with PHP7) be 1 for any value under 'number'.
Conclusion: You need to transform it somehow in the Api itself. For example by decoration of the ApiPlatform\Core\DataProvider\Pagination service (api_platform.pagination).
API_URL?page[number]=2
print_r($request->attributes->get('_api_pagination'));
Array(
[number] => 2
)
The value of the "page_parameter_name" parameter should be "number" .
api_platform.yaml
collection:
pagination:
page_parameter_name: number
This may not work in version 3
vendor/api-platform/core/src/JsonApi/EventListener/TransformPaginationParametersListener.php
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
$pageParameter = $request->query->all()['page'] ?? null;
...
/* #TODO remove the `_api_pagination` attribute in 3.0 */
$request->attributes->set('_api_pagination', $pageParameter);
}

Search for specific in-reply-to header in gmail api

I'm using GMail Api and I would like to query users messages if they have a message with header
In-Reply-To: <specificMessageID#service.com>
I haven't been able to figure out how to do this.
I guess method should be messages.list but there are no query like: rfc822msginreplyto:
If there is no such possibility do you think, it is good practice to fetch last 100 users emails and check it manually?
You could list messages with q = rfc822msgid:msgid#example.com and then get the thread of that message to see what the replies are.
Message.list returns a list of Users.messages
Message.list does have a q method.
q string Only return messages matching the specified query. Supports
the same query format as the Gmail search box. For example,
"from:someuser#example.com rfc822msgid: is:unread". Parameter cannot
be used when accessing the api using the gmail.metadata scope
So you can test it by searching in gmail itself if you can get it to work there it should work VIA the api.
In-Reply-To: <XXX#gmail.com>
I tested that and it appears to work.
I am not sure which client library you are using but most of them have an optional parameters option when creating the request that will allow you to add the q parameter.
Update:
Test your query from Gmail Search
The request you send must be accurate you must not add spaces on the end or remove the space after :
In-Reply-To: <dddi#gmail.com>
Example:
https://www.googleapis.com/gmail/v1/users/me/messages?access_token=XXXX&q=In-Reply-To:%20%3Cdddi#gmail.com%3E
Response
{
"messages": [
{
"id": "152377f1efe8d069",
"threadId": "152376d14b187e44"
}
],
"resultSizeEstimate": 1
}
Using try me at the bottom on of the page.

Authentication in liferay pages

We are having a portlet on a liferay page. We want to put up up a permission on every action method that is performed. For example on page A we have landed an XYZ portlet. Now we want that whenever there is any action performed form this portlet, we want to check that if the user is having a role to perform this action or not.
It wont be a good approach to put up the code in Action method of the portlet cause we are having approximately 20 such pages and portlets.
Can we have some sort of filter or so, so that each action request is checked if the user is having the access to the content or not.
Thank you...
My idea.
Use a filter to intercept all request
You can add a filter to the Liferay Servlet to check every request.
For that you can use a hook-plugin.
Look at this :
http://www.liferay.com/fr/documentation/liferay-portal/6.1/development/-/ai/other-hooks
http://connect-sam.com/2012/06/creating-servlet-filter-hook-in-liferay-6-1-to-restrict-access-based-on-ip-location/
Issue with filter is that you can't access ThemeDisplay or use PortalUtil.getUser(request).
So you must use work around like that :
private User _getUser(HttpServletRequest request) throws Exception {
HttpSession session = request.getSession();
User user = PortalUtil.getUser(request);
if (user != null) {
return user;
}
String userIdString = (String) session.getAttribute("j_username");
String password = (String) session.getAttribute("j_password");
if ((userIdString != null) && (password != null)) {
long userId = GetterUtil.getLong(userIdString);
user = UserLocalServiceUtil.getUser(userId);
}
return user;
}
Filtering the request
To filter the request you must get :
page id (Layout id in Liferay)
portlet id
portlet lifecycle
One more time using a filter is a pain because you can get the ThemeDisplay. These params are easy to get (with real object instancee) with ThemeDisplay.
So you must get this as parameter in the request.
final String portletId = ParamUtil.get((HttpServletRequest) servletRequest, "p_p_id", "");
final String layoutId = ParamUtil.get((HttpServletRequest) servletRequest, "plid", "");
final String portletLifecycle = ParamUtil.get((HttpServletRequest) servletRequest, "p_p_lifecycle", "");
Lifecycle details :
portletLifecycle is a int and the meaning of value is :
0 : RENDER
1 : ACTION (the one that interests you)
2 : RESOURCE
I think that with this data you can be able to define if user can or cannot make the action.
You can get user roles from the user.
You can get the current page and portlet linked to the request.
And you can know if the request is an action request.
Good luck with Liferay.
You can add freely configurable permissions to Liferay, see the Developer Guide for detailed information. My first guess on this would be that these affect "model resources", e.g. the data that your portlet is dealing with, rather than portlet-resources, e.g. permissions on the individual portlet itself. Think of portlet-permissions as permissions that are defined by Liferay, model-resources as permissions where you can come up with your own vocabulary on the actions, e.g. "UPDATE_ADDRESS" etc.
These permissions will typically be tied to roles, which are granted to users/usergroups/etc.
Based on this variability, it depends on the nature of your permissions if you can write a filter to generically check permissions, or if it depends on more than the individual action call.
If you determine that there is a generic solution, look up PortletFilters, they behave just like ServletFilters. These can easily provide a home for permission checks.
It's quite hard to cover this topic in such a short answer, I hope to have given enough resources for you to continue your quest.
You can abuse some existing portlet permission like "Add to Page" and set it to roles that should call the action.
And by the rendering and action phases validate "has the user necessary permission".
Or you can create new permission and configure it by portlet-configuration. This way is cleaner, but difficulty.

Tridion 2011 - Engine.GetObject overloads

I found the following difference between the old VBScript API and the .Net API:
In the old VBScript API it's possible to invoke "TDSE.getObject" to retrieve a Tridion object passing by the webdav path, an integer to select how to open it (read only, read and write, etc) and the ID of the publication where there is the exact element of the blueprint we want.
In the new .Net API all I found was "Engine.GetObject" but it only receives the TCM ID or the webdav path of an element.
Our scenario is the following; in the old VBScript code, this overload of the getObject method was used to avoid some permission issues detected while using TCM IDs instead of the webdav paths and because it's much more handful when you need to copy the code between different environments (see DEV, PREPROD and PROD for example), avoiding changing TCM IDs.
So my questions are:
Is there and overload like the old one in the new .Net API?
If not, is there a way of retrieving items by webdav keeping in mind that some of them could be localized and changed from their parent? (the old way works with this, if you send the root webdav path it will retrieve local objects even if their names aren't exactly the same as the parents)
Thank you!
Do you want to be able to use the webdav url of the top-level item, and specify the publication id from which to get the item?
I would create an extension method on Engine that does this for you:
public static T GetObject<T>(this Engine engine, string webDavUrl, int publicationId)
where T : IdentifiableObject
{
[logic to retreive the item and then if needed
get the correct tcm uri and get the intended item]
return item as T;
}
However, this is quite an expensive operation since you get two objects instead of one. So I dont know if I would use this method very often.
Here some samples
IdentifiableObject item = engine.GetObject(new TcmUri("tcm:5-677"));
//will give you the latest approved version in the publication 5.
IdentifiableObject item = engine.GetObject(new TcmUri("tcm:5-677-v0"));
//will give you the WF or Editable version.
TcmUri uri = new TcmUri("tcm:5-677");
uri.PublicationId = 6;
IdentifiableObject item = engine.GetObject(uri);
//will give you the latest approved version in the publication 6.
Engine.GetObject has 4 overloaded method.
GetObject(Session, string)
GetObject(string)
GetObject(TcmUri)
GetObject(Item)
You can check the Tom.Net Api for more details.
Actually, using Engine.GetObject Method (String) should work.
public virtual IdentifiableObject GetObject(
string itemUriOrWebDavUrl
)
You can do something in this way:-
Get the Object based on WebDav URL
Get the TCM ID from this object
Based on your publication, modified your TCM ID accordingly and do your stuff
OR
Try something this way too:-
Repository testRepository = (Repository)session.GetObject("tcm:0-2-1");
Component testComponent = (Component)testRepository.GetObject(webdavURL); //Assuming actual TCM ID is "tcm:1-3"
Console.WriteLine(testComponent.Id); // should show "tcm:2-3"
// Do Your Other Stuff