Template Function Code review? - secure_img
Added by Christian Meyer 13 days ago
Hello!
I created this template function to enable "secure" images...
It should discourage others to try to scrape Images from docroot ...
This also enables showing pictures only to logged in users and keeping this data private.
It works, and I just want to give it to the community =)
If you spot things that might be done better, please let me know.
bool secure_img(Wt::WTemplate *t,
const std::vector<Wt::WString>& args,
std::ostream& result)
{
if(args.size() < 1)
{
Wt::log("info") << "Template Function secure_img needs at least 1 argument";
return false;
}
// find if style classes are given
auto classIndex = std::find_if(args.begin(), args.end(), [](const Wt::WString& ws) {
auto s = ws.toUTF8();
return s.size() >= 6 && s.compare(0, 6, "class=") == 0;
});
// find if alt text is given
auto altIndex = std::find_if(args.begin(), args.end(), [](const Wt::WString& ws) {
auto s = ws.toUTF8();
return s.size() >= 4 && s.compare(0, 4, "alt=") == 0;
});
auto imgFile = t->addChild(std::make_unique<Wt::WFileResource>());
imgFile->setFileName(Wt::WApplication::instance()->appRoot() + args[0].toUTF8());
Wt::WImage wimg{};
wimg.setImageLink(imgFile->generateUrl());
if(altIndex != args.end())
{
// somehow "" is not part of the string, even if it is given in the template
auto altText = (*altIndex).toUTF8().substr(4);
wimg.setAlternateText(altText);
}
if(classIndex != args.end())
{
auto classesString = (*classIndex).toUTF8().substr(6);
wimg.addStyleClass(classesString);
}
wimg.htmlText(result);
return true;
}
Usage: ${secure_img:/path/to/approot/img <alt="Optional Alt Text"> <class="optional style classes">}
First Parameter is Path, Order of 'alt' and 'class' does not matter
Currently I have not tried to use another bound variable to load path from db.
UnTested: ${secure_img:${db_img_path}}
: Should this just work, or is there something to make sure of?
Any comment is welcome =)
Cheers
Christian
Replies (1)
RE: Template Function Code review? - secure_img - Added by Matthias Van Ceulebroeck 6 days ago
Hey Christian,
Thank you for the contribution!
Be mindful that this exposes the filename of the image. If it's guarded by a login, that's fine, though.
Also, do note that for agents detected as bots, this may result in unexpected behavior. Those agent's session will be closed quickly, but they will be served the link to the image.
When they try to load it, the application may detect that as a new session, and serve a new set-up page. Depending on how this is handled, the bot/crawler may encounter a loop.
We encountered something similar a while ago in an application of our own. A simple robots.txt
file solved it for us.
As for the DB substitution. I don't think that will immediately work. The substitution doesn't take place until rendering time. At that point both function resolving and eventual string substitution take place, so they would "collide", and I think the more deeply nested $
would be omitted.
You probably need to look at changing WTemplate::renderTemplateText().
My last claim is unverified, so I may be wrong!
Best,
Matthias