GELScript - Email to multiple recipients - jelly

How can I send a gel:email to multiple recipients? I have records with 3 email addresses in each and I want to send the same email to all 3.
This is my current code:
<core:forEach items="${getDetails.rows}" var="row">
<core:set value="${row.Manager_Email}" var="manager" />
<core:set value="${row.Delivery_Manager_Email}" var="deliveryManager" />
<core:set value="${row.Director_Email}" var="director" />
<core:choose>
<core:when test="${status == 1}">
<gel:email from="Clarity_Do-Not-Reply#gov.nl.ca" fromName="Clarity Administrator" to="${manager};${deliveryManager};${director}" subject="Notification: Project is due to finish within 7 days">
I've tried that and:
to="${manager;deliveryManager;director}"
Neither seem to work. The doc says they can be split with the ; but it doesn't seem to be working. What am I doing wrong?

Does it work with just one of them? I would start and establish that the mail server works in this environment. Choose one of those variables and print it out. If it's not what you are expecting then fix your query or wherever you are getting those bound variables. If it is correct then remove the other two recipients and establish that you can send an email successfully to just one of the recipients. If that works then continue troubleshooting.
If it doesn't work then you may discover that your mail server does not allow relaying, unauthenticated services or sending mail from a non-existent email account. You can start checking those things.
One of the issues with both the GEL email tag and the CORE email tag is that it doesn't support including the same email address twice. If you check your project you might find that the same resource is listed as both delivery manager and manager or director, etc. This is a problem for the tag.
You can get around this by placing all recipients into a data structure that doesn't allow duplicates (like a hash map/set) and then iterate them out back into a semi colon delimited String.
There are probably lots of examples of this type of thing on regoXchange, a huge repository of free GEL scripts and Clarity related customizations and development.

This approach that was in your original script example is the correct way to do it: to="${manager};${deliveryManager};${director}"
That is, using a single delimiter type (semi-colon in this case) to separate each evaluated variable value.
The style from your second attempt definitely will not work as ${manager;deliveryManager;director} is not a valid JEXL expression.
There are additional points to be aware of, such as:
Each of the values in the to attribute should not have anything else that can be mistaken for another delimiter type (e.g. no spaces or commas), as you may not mix and match.
Only use the email address directly, meaning some.one#somedomain.com and don't use forms like "One, Some" <some.one#somedomain.com>
Make sure none of the email addresses are duplicated in the list. Every address must be unique. As mentioned in the answer provided by #coda, you can filter duplicates out with some extra GEL or you can put the logic into your query (the row source) to de-duplicate.
If this is running in a SaaS environment, make sure none of the user addresses you are picking up are among the defaults for some built-in user accounts like username#mailserver.com or similar, as they have resulted in emails being filtered out before sending.

Related

How should I name an endpoint that checks whether a user has authority to edit a resource?

The background first:
I have an application where a logged-in user(employee) X can see a list of all other users (employees). If the logged-in user X is a manager (their designation), then they can also edit certain attributes of the users they manage. For example, the location, designation, and the department of the user being edited. It should be noted X can edit only those employees who report to him/her, which means there are users which X is not allowed to edit.
When X clicks on a user to edit it, they navigate to a page like http:myapp.com/dashboard/editUser/<ID_OF_THE_USER_BEING_EDITED>
Obviously, X can get smart and manually edit the URL and put in the id of a user they are NOT allowed to edit, so before loading the edit form I need to check whether X has the authorization to edit user Y.
if X is authorized to do so, then that page displays a form (with the current attributes of the users pre-filled in the appropriate fields) to edit the user. Else, I display an 'Access Denied' kind of message.
Right now I have created a very badly named temporary endpoint (/api/v1/maybe_edit_user/?jwt=<TOKEN>&userId=<USER_BEING_EDITED>).
This grotesque-looking endpoint does 2 things:
It extracts the currently logged-in user from the token, and checks whether it has the required access level to edit the user (passed through the GET parameter userId)
If yes, then it returns the current attributes (name, email, location, designation, and other stuff) in the response, which is then pre-filled in appropriate fields when the form is displayed.
Once X submits the form, a PUT request is sent to another endpoint (/api/v1/users/<USER_ID_OF_Y> PUT) and the user Y is updated.
While this works, I don't find it attractive. I am trying to learn to write better, cleaner, and more organized code that is compliant with the standards.
The best practices for REST suggest that all endpoints should be nouns. My endpoint, on the other hand, is not even a simple verb. It's a god-forsaken phrase at the very minimum.
So, the questions here are:
How should I name my endpoint.
Should I use a single endpoint to check for permission, AND fetching the attributes of the user being edited, like I am doing right now? Or should I break them into 2 separate endpoints?
The fact that there is an access control list is an unrelated concern; ignore it.
Resource identifier identify resources. Resources are generalizations of documents.
You want an identifier that is consistent with the production rules of RFC 3986, and it is often convenient (but not required) to choose spellings that enable leverage of URI Templates (RFC 6570), but otherwise the machines don't care.
That means you can choose a spelling that makes things easier for humans; you get to choose which humans get priority here.
it returns the current attributes (name, email, location, designation, and other stuff) in the response
That's your hint as to what the document is; some sort of digest of Bob's... profile? employee record? dossier? that is apparently optimized for use in this specific kind of form.
So the identifier could be as simple as
/this-specific-kind-of-form/source-data/Bob
and a request might look like
GET /this-specific-kind-of-form/source-data/Bob HTTP/1.1
Authorization: Bearer <token>
The implementation looks largely like your sketch - verify the token, compare the claims to those that are required, and return either the resource or some flavor of Client Error (4xx).
The best practices for REST suggest that all endpoints should be nouns.
Don't read too much into that.
Notice that all of the following resource identifiers work:
https://www.merriam-webster.com/dictionary/get
https://www.merriam-webster.com/dictionary/post
https://www.merriam-webster.com/dictionary/put
https://www.merriam-webster.com/dictionary/patch
https://www.merriam-webster.com/dictionary/delete
You can click on any of those links, and your browser will create the correct HTTP request, and the server will do the expected thing.

Firestore Security Rules - check if field is a valid email address

How can I verify if an incoming field is a valid e-mail? Is there a way to use string-functions or anything in Firestore security rules?
Example:
Let's say I have a Create-Request with a field called "email". In my Firestore security rules, I would like to check if the email is a valid email address:
contains '#'
ends with either .xx or .xxx (a casual country-domain-ending)
has a '.' before the last three or two letters of the email
the '.' does not follow directly after the '#' - at least two letters have to be in-between
So that e.g. example#emailprovider.com gets accepted, but not example#.com.
I know that this check is quite extensive and further would like to know if it makes sense to introduce such a validation to security rules?
You can use rules.String.matches.
See
https://firebase.google.com/docs/reference/rules/rules.String#matches
https://github.com/google/re2/wiki/Syntax
How to validate an email address using a regular expression?
Performs a regular expression match on the whole string.
A regular expression using Google RE2 syntax.
If you want to set only email address then It's necessary to validate the field as email address.
I found an example of a regex (and adjusted a bit):
^[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,5}$
The source of this is at the bottom of the following page:
https://firebase.google.com/docs/reference/security/database/regex
You should also take into account the note as well:
Note: THIS WILL REJECT SOME VALID EMAILS. Validating email address
in regular expressions is difficult in general. See this site for
more depth on the subject.

Drupal: Edit !name variable in my Drupal to first name?

I’ve a bit of annoying problem with a Drupal site. I’ve a “recommend to a friend” field where one can send an article link to an E-mail address. The problem is, that it uses the variable !name in the mail and when I’m receive a mail, it uses the name before the “#” in my mail.
I use my mail as username, so if I’ve registered a user with the username: johndoe#google.com it will present the !name variable as johndoe.
What I want is to display the first name (and maybe the last name) so it says: John Doe recommends this article …
But how can I do that? I’ve search like crazy for the setting.
Thanks
Sincere
- Mestika
To replace user names in quotes by reals names it's necessary to replace Phorum´s standard function for quoting. Since it only makes sense to have one module modifying the quoted text, you can disable this one part of this module. Use System Sanity Checks to control if there is only one module using the quote hook. The default value is "disabled".
TUV Rheinland of North America
You could also try the Custom Tokens module. I use it to get text from my user's Content Profile.

ASP.NET MVC 2 EditModel include Id? Securing Id is not tampered with

I am looking for some best practices when is comes to creating EditMoels and updating data in an ASP.NET MVC app. Lets say I have a Url like so /Post/Edit?Id=25
I am ensuring the user has permissions to edit the specific post by Id on the Get request and the same for my Post in the controller. I am using the ValidateAntiForgeryToken.
Questions: Should I include the Id property in my EditModel? If so, Should I encrypt it?
The problem is I can use FireBug to edit the Id hiddedinput and edit a different post as long as I have permission to do so. This is not horrible, but seems wrong.
Any help would be great!
There are several ways to prevent this.
The first - don't send sensitive data to the client at all. Keep the post id in session variables, so the user can never edit it. This may or may not be an option depending on your architecture.
The next approach is to convert the direct reference to an indirect one. For example, instead of sending postids = {23452, 57232, 91031} to the client to render a drop-down list, you should send an opaque list {1,2,3}. The server alone knows that 1 means 23452, 2 means 57232 and so on. This way, the user can't modify any parameter you don't want him to.
The last approach is including some kind of hash value that adds as an integrity check. For example, suppose you have 3 hidden fields in a html page - {userId=13223, postId=923, role=author}. You first sort the field names and then concatenate the values to get a string like postId=923&userId=13223&role=author. Then, append a server secret to this string, and hash (SHA-1 or MD5) the entire string. For eg. SHA-1('postId=923&userId=13223&role=author&MySuperSecretKey'). Finally add this hashed value as a hidden parameter. You may also want to add another hidden field called ProtectedParameters=userId,postId,role.
When the next request is made, redo the entire process. If the hash differs, balk the process.
Security wise, I have listed the options in decreasing order. At the same time, its probably in the increasing order of convenience. You have to pick the right mix for your application.
I don't think you should worry with that, if the user does what you said, i suppose that you'll know who edited what, so if he edits the wrong post, doing as you said, you can always remove his edition rights...
If you can't thrist your users, don't let them edit anything...

Guarding against user-input in a dropdown list?

Should we guard against unanticipated user input from dropdown lists? Is it plausible to expect a user to somehow modify a dropdown list to contain values that weren't originally included?
How can they do this and how can we stop it?
Absolutely check for that.
Do something like this pseudo code on the receiving end:
if { posted_value is_element_of($array_of_your_choices) }
//processing code
else {
//prompt them for good input
}
So for example: Your dropdown list is of Primary Colors they'd like their house painted. You'd have (in PHP)
$colors = array('red', 'blue', 'yellow');
if in_array($_POST['color'], $colors)
{ //process this code! dispatch the painters; }
else {echo "sorry, that's not a real color";}
Edit: This is certainly possible. If your values are being submitted via a GET request, then the user can simply enter www.example.com/?price=0 to get a free house. If it's a POST request, it may seem a little more difficult, but it's really not:
curl_setopt($ch, CURLOPT_POSTFIELDS,"price=0");
People could just use cURL to directly manipulate a POST request, in addition to a trivially large number of other clients.
A user can simply hand-write a HTTP request which has has filled in malicious data. For GET requests, for example, you may have a "State" dropdown that lists Alabama, Arkansas, etc. He may put http://example.com?state=evilstuff just simply into the browser url bar.
This is easily prevented since you already know exactly what is in the dropdown list. Simply checking to see if the input is in that list or not should be sufficient to prevent against injection-like attacks. If he puts in something other than a valid state name, throw an error.
This can only be done by modifying the HTTP response. So,
yes, it can be done and you need to safeguard against it (i.e. check if this can be a security threat and, if yes, validate the input), but
no, you don't need to bring a "nice" error message, since this cannot happen to a normal user "by accident".
When I'm bored, I edit drop-down lists in web sites just for fun. Mostly it just breaks the site, but at least once I could have gotten free or drastically reduced prices on tickets just by playing with the site's hidden fields. (Alas it was for a company I worked for, so I had to instead report the bug.)
Yes, a malicious user can submit data to your server without ever using your form, and could submit data that's not normally included in your dropdown list. This is a trivial form of attack that's often exploited in the real world.
Always check for valid input!
Some of the other answers are absolutely correct, you MUST validate on the server-side ANY data coming from the user side.
At work, we use tools such as the Firefix plug-in Tamper Data to manipulate and view data thats being posted to the server, after any client-side (javascript) validation has been done. Also, you can even use simple tools such as Firebug to visibly alter drop-down boxes to contain values that weren't put there by the server before submitting it.

Resources