problem to configure public key on google audit email api - google-admin-sdk

I need a help! I'm trying to use the google auditing API (https://developers.google.com/admin-sdk/email-audit)
Im getting a problem to configure the public key on API (https://developers.google.com/admin-sdk/email-audit/auth#example), receiving the following error:
The value of attribute "value" associated with an element type "apps:property" must not contain the
'<' character.
Im following the documentation payload:
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<apps:property name="publicKey" value="<em>my public key in base64 here</em>"/>
</atom:entry>
One example of public key that i generated and encoded on base64:
LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptUUlOQkdJOW96c0JFQUNkTWlUajY2UUNJeTlOSjNzQzFGS1dlaFZDaTRKaGRtZDVhemtnMlh5WlM5RXNGT2hDCkJ6elVlT2lyRnRaKzR2c3pQZUdNT3A5eXlKS0dCcnk3ZUVWV0JzZTE0aHFzSjJiY1NRSEFOMnpVdDl6WlZNbzkKS3lBdGZxNytxTGRhNjhMbUpmM1drT1RxVFVCWnZ5OTQvYnhCMmR2UkR0ZWtCRFo2TlZIMVpObFJLOXY3Si90cgpNYmFvRnhiSmF4RlA4ZkZrVGxhcS9aY2ZCRmcxOWV0YkpHWUdTSU9yRlZ5MXVyQmlUOGx2TFhEbi81a2JNc0o1Cms3am5sUUNqcDcrN0RLSXVlSXBISGZBY2xNaitreEl4WmdlZElVbzJ0RTV3UVVIYmNmSU96a010UEFFWENUTUgKZW9GR2drTVBaaHB1NlhhbFY0RnlHZzdPMEtLWGcweHFtdjI3UDd1a0VlaFRkbzVLZitzZW5YZzVEbVpLQm9mRwoyejlzQUg1MXplWXZkVHhDSkdtdUprdWJPMEcvTFhxOHlGRW5oZEkyZjNkazQwNUZ4UlJna1BGU2tOYjFVS21mCklCSU1uM0VDVG1qK1JOWE9aS0Rqd2hmdHpkRS9KVGpueU1JVUFWR0VEWGtGdEVXTVRpSmIrVURZQi9odm9QS2sKdUNXNUNDNWtuOG14Z2x4eWxIaUVhQWJ6dTQ3MFBaaW9NTWo5VHk2VGZOVXZDOXJsRGszSEsreUpIaWJqWmxOagoxREdaN01yZWs4STV0ZVlVcmtZYVNDNUt4SVhSRjZwaEIyZUdUdzh5SEp3UUd3RURPL1E1QmJ3Q2dqREN4VS9ICkUyTFF4MURZeFU1Q1l4U1dIR0xzcVkrQUxKNGlsSXdNWEZERFZOdzRFVTl0Yis3cWdTajhXR2FRM1FBUkFRQUIKdEE1S2I4T2pieUJrWlNCQmMzTnBjNGtDVkFRVEFRZ0FQaFloQkJnbEtEbGhsVHFpUStRVUd2WFc5blJHV05JbQpCUUppUGFNN0Foc0RCUWtIaGg5eUJRc0pDQWNDQmhVS0NRZ0xBZ1FXQWdNQkFoNEJBaGVBQUFvSkVQWFc5blJHCldOSW1CbDRQL1JUeDlkbW1oMitXUE9jRUpGMXcvVkZqRFBMbkFWV3VSQnRKYmd2SVlETVdBUHpaTC9OYlRCL0wKUE1BYVdqdFlsRUZrZkpJMGxjdnU0L2F0R0JydDBIeGZFMW5FRjkzME5HcGNSaU80blcyd1hZSUhmaHg2ZnRlZwo3a283TDVPN21jMDgwWnpQRXQrSjEzZTZnSVdwbWExSXh3djRFRTVCb1NoQnpTOVlOWjNVQUJPLyszTnhCZHF2CloybldCcVR0cXpWb2Z4SGJPejBLRGJLclNLaUNmZy9EWmxzYVBES2FLMURQOU8xU3pJcURJWGQ0Q25RSWw2WUEKQjJPV0cvTE05OWV5Y2pxQitVTWw3ZzR4c1hBRGV1SG12SzVUSDUwRzgvRGpsSmZtWllkdUZiSm5hZGlHUnZWbApzOVpFNnZDRzl2ajNxQUFFVDhIcHNJUldTaWNGZHczVzFYV1RDdE1pYWE1M3ZidkhVaWw5QnI5VWxWMjJLbThkCmdLM3VsZXVCMmg4WnRXeEVIbE9kVXBDQ3RsNVp3RVBMeTNTSWIrL3lnQWV5cTAxanFOY0VlZmg1emk0VXNIZmQKdXZDVDZ0T0E2bmwyTVZuSDhzWTRHUlcrM0xqZjNJSVlRNzQ3QXQ3bGRVTDJCdTUrQng1bUlEV0QzZ0kvWnJ4LwpFQVU2QWx4eTI0YWJQcG90VlBYQW1BKzMzVDZsR2dWeXUwV2U3Vm14RkxucENmby8xQXlROUNWOVhIb1NhdjhmCkRJYXNtc203VnNaYXd1VTRoVi9DV2FPcXQ4WlUzRndyRDI0NElIR2c2L1RQZU1DWlRrMVhVdEVKdW9PcUpyb04KdDVXay8vZTI2VDh2akFWQWhHOWFzNE5HQnRLbUlDdlJpUkdEalEwQ1A2WEMzOVFEeEF3VnVRSU5CR0k5b3pzQgpFQURRNGl2bTQ2YTAzTXJZcUZjay90VWYxZTdCcTNtOVdVbkVOTEdtQ1RGdG1TTVJlQm5DZEx0bTV3K3piS1hLCmZMYzdrUTFNcHJMbTJVMk1zdk9XeGVjNk91eWxXeCtxOXB5UlR1NU5VR0txN1ZPUVZRYW9TNCs5VHpTQTBETmUKcUxjbWhIakhvSVNJZWVEZXRIWEZ1ZklNcHMvVUxCSndWUzZKYzdOaUhNNmp6TVMxS1hkVzJlbEFOdDdYNXBTYwpsLy9wL1VYTWxkSmZqZHMxWmljWFlkZWtGeTVyR3pHT2s4ZEhmMDRTS0Vsa1d0Ry9xZnZqb1FoVFRuOHZFTFZXCmpxUjlwS08yVDhDNXB1VFFwQld1Z0lGMFVaalAvcWVZL0xDMmVOcHNqczZ1SjllbU5GRXZ6YkJlSjlQOWhLUzQKdHUvZWxtSWFqczBPdFpycWMrTWNSQmFvcVVWQ1BETkFabVRWTnkyQ3l1MTFkQUJIRVozQWZBTE1qNXB4TmJiQgpHTWkxblByY3lqdzFOd05CV3VKTDdaQlZ6d2J3bjVQcHNlWVB5Vi93TWszd3RWNi9XVW9vdTYxbDI3RDdnY1lKCmlyYXN4R0pmSWR5WkNVSEFmNHNIN3MxM1VRb2puVHdodGlBWFpIaWlSTlBDVWF2VXFuSDVlZ3UrOElhKzZnTDkKeGE0cUI5a1lqc1cyem1LbTY4QkpLWGJKb1ZleGdOaVVnajYxZkphOC85UTJyQ2V5Y1VpdXRDbzFsUDFVQzhYMQplekNBNi8vL0hxQUxoU2ZuQ0hONHZRMzUvdlNGaHo3LzREbTBzSjI3Qk5leG0vQ1JFYXNBdVVYVWJFdXF4Q2VVCkZCMHVDTlo4cXkxT2FpWnl0cDFCaDBjYjlQWDdaSE9QQmpMeWpGaEZCak16RlFBUkFRQUJpUUk4QkJnQkNBQW0KRmlFRUdDVW9PV0dWT3FKRDVCUWE5ZGIyZEVaWTBpWUZBbUk5b3pzQ0d3d0ZDUWVHSDNJQUNna1E5ZGIyZEVaWQowaVpNT2cvK0kzejdnOElCWE81SThaNmY4cjhVcVpRNjE0dlkyUGtUSk1kK1c5SnZyTmFBWDJOdXBxMFk1ZjlLCkFiSTVCcjBaOFp1MjQ2NjVZZFQyUkNOS3VDa0dmZUc3WWlvTnhDREc2dys2c1o3SWtWQjBhcDJwYk8wb1ZBcFgKYzlWc3RzY2p2dkJheC91djgrZElGUmpKUithb21KRzFURVpVcWNvMEJVcHRXRUs3azN5SXAyUlBDVW5oeEcySQpZbUUwMmEwNkljdE9oeUtBUW9FM2ZRQmdLUGN6Z0tnbWNCdjhreDU4Qld1UEkyZk9MMjhQSm1jSzg5ZWpFdEwxCnRoNHh2dE9ibXl6SkFZTUduMHYyenpvV0NJUENGL2FIaVhpOEFvSEJRRExpeVpnejRla2Q0Q3B3TEtJUmJxYzQKZkkzOEgzQlQvQmxML3Bic0RHeXUvc2NVbUVsc3MrbnhrOWhkZVdwdCt2TTFGc2duN1RCY0FUb21zaVBVSG1obQpBUCsvdFRMVnNBb3FnMHpoanBaNVhBS28yUHVGZk42M2EvMGwxOXR2SmxGa09ZT0JEYVZKOWoxZmhuclBaSnJmCjJwODNLM1lhZ3hIWEQvNUFhVGNoM0Z5V2Nja3RmVDkyME5LY3AzUHNtZnN2bU5HdUYrRnlmYVpCQXh4MmtkWmgKTG13MEx6NVE3ME8wd1J4NnJZNmN0bHRvdnVlY29IS1VTWWdPamFsNzc3cG5tODRYb2FkdXdUdDVnUXlrdmlScwpiVHhZMytaWWM4eFJ1QjJYaTVkZGFUWkw2bEJoclpDMHdDWnI2L2hPYTVhUFdVVStGeFdtZkpsZ3A0Z1VkeVIwCldkK1FOMXNMZmt0b2Y5amJXeFRwNjd5SUpBMDV6c2VpdUp4OEszTmxDWk80YTN1T2xuUT0KPWZmZWsKLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQ==
If you check on base64 decode for example, you can see that its a complete public key...
Any idea?
Thank you!

The error message points that there is a non valid character being passed on the "value" attribute, in this case the <> characters are non valid within the value field, checking your example you are adding it like this:
<apps:property name="publicKey" value="<em>my public key in base64 here</em>"/>
Where the "value=<em>my public key in base64 here</em>" is being passed with the "<>" characters, even though the documentation states that "<em>" and "</em>" is passed you can still just remove the tags and add the public key without them like this:
<apps:property name="publicKey" value="my public key in base64 here"/>

Related

Can not upload image to API with Postman (File field is required) .NET6

I am trying to send an image file to api controller with postman. I am working with .Net 6.
The problem is an error always appears as in the image, postman screenshot
That is my code
namespace WebAPI.Controllers
public class Image
{
public IFormFile file { get; set; }
}
[Route("api/[controller]")]
[ApiController]
public class CarImagesController : ControllerBase
{
[HttpPost("add")]
public IActionResult Add([FromForm] Image file)
{
if (file != null)
{
return Ok();
}
return BadRequest();
}
}
If it is eligible to use, I want to change argument of Add method, i mean
public IActionResult Add([FromForm] IFormFile file)
and I want to delete Image class after that change.
Thanks for your help
Your code is correct, I create a sample using them, they all works well. The issue might relate that when using Postman, the key value contains spaces, such as file .
You can check the following screenshot: when using file key, everything works well, but if using file (with spaces), it will show the 400 error.
your code is all fine but you have an issue in postman. Check the formField key file. It has whitespace bcz you pressed enter there. Just remove any extra space and it should work.
I know it sounds stupid, but that's the issue. Postman takes whitespace and new lines seriously as key and values.
see the arrow and ... , that's the indicator.

Extra string & pipe character in Laravel Cookies

In a Laravel 6x project I'm working on I'm setting a cookie with:
Cookie::queue('remember_me', json_encode(['uid' => $user->id, 'token' => $token]),2628000);
I'm reading the cookie and decrypting it with:
$cookies = Crypt::decrypt(Cookie::get('remember_me'),false);
This works well, except that the value of $cookies has an extra pre-pended string and a | delimiter in it:
e80cd502fec2a621b624ead8eb1cc91a2e94846b|{"uid":872,"token":"l1214065120208k"}
I can work with that obviously to get what I need but I have been unable to find anything on why that string and | are being prepended to the cookie. Any explanation or documentation link?
I did find another thread here with a similar question but no answer:
How to decrypt cookies in Laravel 8
I also found a thread suggesting that Laravel 8 adds the session_id to the cookie string. Is that what I'm seeing here?
Thanks,
Michael
This value looks to be an HMAC-SHA1 of the cookie name with v2 appended to the end.
This logic is implemented in the CookieValuePrefix class in Laravel and the code looks like so:
public static function create($cookieName, $key)
{
return hash_hmac('sha1', $cookieName.'v2', $key).'|';
}
This is used in the EncryptCookies middleware when encrypting and decrypting accordingly. The relevant source code is:
// in decrypt() function
$hasValidPrefix = strpos($value, CookieValuePrefix::create($key, $this->encrypter->getKey())) === 0;
$request->cookies->set(
$key, $hasValidPrefix ? CookieValuePrefix::remove($value) : null
);
// in encrypt() function
$this->encrypter->encrypt(
CookieValuePrefix::create($cookie->getName(), $this->encrypter->getKey()).$cookie->getValue(),
static::serialized($cookie->getName())
)
I put this logic into a CyberChef page here to test it out with some local cookies I had and verify the output matches and it did. If you go there and plug in your app key (preferable a disposable one) you should see it output the hash value you have in your question.

Use a view to get the same suffix like maindomain name

I have some documents, how can use a view to get the document which have the same domain name for their email address. like all the document with #gmail.com or #yahoo.com, if endkey can get that results?
Here is what I wrote a view on map, But I do not think this is good idea
function(doc) {
for (var i in doc.emails) {
if (doc.emails[i].emailAddress.toLowerCase().indexOf("#yahoo.ibm.com")!=-1) {
emit(doc.emails[i].emailAddress.toLowerCase(), doc);
}
}
}
}
To make things clear, the endkey parameter is not looking for a suffix. Startkey and endkey are like the limits of keys to get. For example, you could get the document with the id 1 to the id 10 startkey="1"&endkey="10" .
In your case, you want to make a view that will group your documents by their domain name. I created a design document with a byDomain view. The mapping function looks like this :
function(doc){
if(doc.email){ //I used the document's property email for my view.
//Now, we will emit an array key. The first value will be the domain.
//To get the domain, we split the string with the character '#' and we take what comes after.
//Feel free to add more validations
//The second key will be the document id. We don't emit any values. It's faster to simply add
//the includes_docs query parameter.
emit([doc.email.split('#')[1],doc._id]);
}
}
Let's query all my documents to show you what I have
Request : http://localhost:5984/test/_all_docs?include_docs=true
Response:
{"total_rows":4,"offset":0,"rows":[
{"id":"7f34ec3b9332ab4e555bfca202000e5f","key":"7f34ec3b9332ab4e555bfca202000e5f","value":{"rev":"1-c84cf3bf33e1d853f99a4a5cb0a4af74"},"doc":{"_id":"7f34ec3b9332ab4e555bfca202000e5f","_rev":"1-c84cf3bf33e1d853f99a4a5cb0a4af74","email":"steve#gmail.com"}},
{"id":"7f34ec3b9332ab4e555bfca202001101","key":"7f34ec3b9332ab4e555bfca202001101","value":{"rev":"1-53a8a9f2a24d812fe3c98ad0fe020197"},"doc":{"_id":"7f34ec3b9332ab4e555bfca202001101","_rev":"1-53a8a9f2a24d812fe3c98ad0fe020197","email":"foo#example.com"}},
{"id":"7f34ec3b9332ab4e555bfca202001b02","key":"7f34ec3b9332ab4e555bfca202001b02","value":{"rev":"1-cccec02fe7172fb637ac430f0dd25fa2"},"doc":{"_id":"7f34ec3b9332ab4e555bfca202001b02","_rev":"1-cccec02fe7172fb637ac430f0dd25fa2","email":"bar#gmail.com"}},
{"id":"_design/emails","key":"_design/emails","value":{"rev":"4-76785063c7dbeec96c495db76a8faded"},"doc":{"_id":"_design/emails","_rev":"4-76785063c7dbeec96c495db76a8faded","views":{"byDomain":{"map":"\t\tfunction(doc){\n\t\t\tif(doc.email){ //I used the document's property email for my view.\n\t\t\t\t//Now, we will emit an array key. The first value will be the domain.\n\t\t\t\t//To get the domain, we split the string with the character '#' and we take what comes after.\n\t\t\t\t//Feel free to add more validations\n\t\t\t\t//The second key will be the document id. We don't emit any values. It's faster to simply add\n\t\t\t\t//the includes_docs query parameter.\n\t\t\t\temit([doc.email.split('#')[1],doc._id]); \n\t\t\t}\n\t\t}"}},"language":"javascript"}}
]}
As you can see, I got few minimalist documents with the property "email" set.
Let's query my view without any parameters
Request : http://localhost:5984/test/_design/emails/_view/byDomain
Response :
{"total_rows":3,"offset":0,"rows":[
{"id":"7f34ec3b9332ab4e555bfca202001101","key":["example.com","7f34ec3b9332ab4e555bfca202001101"],"value":null},
{"id":"7f34ec3b9332ab4e555bfca202000e5f","key":["gmail.com","7f34ec3b9332ab4e555bfca202000e5f"],"value":null},
{"id":"7f34ec3b9332ab4e555bfca202001b02","key":["gmail.com","7f34ec3b9332ab4e555bfca202001b02"],"value":null}
]}
Let's query only documents with that have the gmail.com domain.
Request : http://localhost:5984/test/_design/emails/_view/byDomain?startkey=["gmail.com"]&endkey=["gmail.com","\ufff0"]
Result :
{"total_rows":3,"offset":1,"rows":[
{"id":"7f34ec3b9332ab4e555bfca202000e5f","key":["gmail.com","7f34ec3b9332ab4e555bfca202000e5f"],"value":null},
{"id":"7f34ec3b9332ab4e555bfca202001b02","key":["gmail.com","7f34ec3b9332ab4e555bfca202001b02"],"value":null}
]}
You can just use a simple map function for this:
function (doc) {
var domain = doc.email.split('#').pop();
// this logic is fairly hack-ish, you may want to be more sophisticated
emit(domain);
}
Then you can simply pass key=gmail.com to get the results you want from the view. I would also add include_docs=true instead of emitting the entire document as your value.
You can read more about views in the official CouchDB docs.

Mule - Pass Parameters to datamapper and access them in xpath conditions

How to pass parameters to datamapper in mule and access them. (In XSLT, I pass them as context parameters, receive them in param and access using $ symbol). I need to do the same thing in datamapper. Any suggestions/links/example are appreciated.
Approach1:
We are using invokeTransformer method in datamapper
output.abc= invokeTransformer("MyTransformer",input.abcdef);
This MyTransformer is a java component which has this default method overridden.
#Override
public String transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
System.out.println("Inside transformer" +message.getProperty ("sessionVariable1",PropertyScope.SESSION));
return message.getProperty("sessionVariable1",PropertyScope.SESSION);
But, the problem is I am not calling this transformer from mule flow. But, invoking it from datamapper. Hence the argument 'message' does not get passed. So, Unable to retrive that session variable to return to datamapper. Is there a way to send this argument(MuleMessage from datamapper)?
You can use input arguments with DataMapper and then refer to them in the output:
<set-variable variableName="testvar" value="value of testvar"/>
<data-mapper:transform config-ref="new_mapping_grf"">
<data-mapper:input-arguments>
<data-mapper:input-argument key="testvar">#[flowVars['testvar']]</data-mapper:input-argument>
</data-mapper:input-arguments>
</data-mapper:transform>
and
output.myField = invokeTransformer("MyTransformer",inputArguments.testvar);
or
output.myField = inputArguments.testvar;
Adding input arguments available in the DataMapper GUI through the input side green plus icon.

DataAnnotation TextArea Multiple Emails

I am using MVC 3.
I have a text area in which user can enter multiple emails addresses. Emails can be separated by a comma and a space. User may hit enter in the box as well.
Is there an attribute that can handle this scenario?
I am using regular expression to check for the characters and it is failing for "abc#abc.com, tyz#tyz.com"
Here is my regular expression:
[RegularExpression(#"([a-zA-Z0-9 .#-_\n\t\r]+)", ErrorMessage = ValidationMessageConstants.EmailAdressInvalid)]
What am i missing here? This regular expression is off the following post:
DataAnnotations validation (Regular Expression) in asp.net mvc 4 - razor view
Out of the box, .NET 4.5 has the System.ComponentModel.DataAnnotations.EmailAddressAttribute found in the System.ComponentModel.DataAnnotations assembly, but this is limited to validating just one email address. Hence, if you have a model that accepts delimitted email address and you decorate the property with this attribute, it will fail since it will treat the entire string as one email.
What I've done is create an extended emailaddress attribute that validates the delimited email addresses:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class EmailAddressExAttribute : DataTypeAttribute
{
#region privates
private readonly EmailAddressAttribute _emailAddressAttribute = new EmailAddressAttribute();
#endregion
#region ctor
public EmailAddressExAttribute() : base(DataType.EmailAddress){ }
#endregion
#region Overrides
/// <summary>
/// Checks if the value is valid
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object value)
{
var emailAddr = Convert.ToString(value);
if (string.IsNullOrWhiteSpace(emailAddr)) return false;
//lets test for mulitple email addresses
var emails = emailAddr.Split(new[] {';', ' ', ','}, StringSplitOptions.RemoveEmptyEntries);
return emails.All(t => _emailAddressAttribute.IsValid(t));
}
#endregion
}
You can now decorate any string property with this new extended attribute to validate delimited email addresses. You can update the delimiters to include any special characters you want to use as well.
Hope this helps!
You not stating what the question is, so I will have to assume from your answer that data annotations aren't working as you would expect.
Having that assumption in mind, its very easy why is it not working: data annotation operates on the entire field, text area in your case. It will work as expected if you have only one email. Since you have multiple emails in that field, separated by comma or space, the field in its entirety doesn't reflect what data annotation for email prescribes and fails.
To answer your numbered questions:
No, there is no out of the box
The regular expression you using doesn't account for multiple emails, but one. The solution in your case will be either to
Data annotation using RegEx for multiple emails separated as you'd like or
Have custom validation attribute doing it for you
Following the links above you will see very good examples of "how to" and hopefully get you going in the right direction.
Hope this helps, please let me know if not.