Should Container be cleared on every search? - solrnet

I am not very familiar with Solr Search, but the following code which some contractors are doing for us looks very wrong to me:
public ActionResult SearchLiveTraining(string searchText, string locationsID)
{
// irrelevant code...
//clean Container
Startup.Container.Clear();
Startup.InitContainer();
// irrelevant code...
}
The thing that seems very strange to me is that Startup is static class and this seems like the sort of calls that should be made once at the beginning of the application... not once for every search.
I am also concerned about whether even though this works fine in testing, if in production when many people are using the page at a time if this will cause problems?
Are my fears justified and should I immediately look to correct this, or is this actually how solr search is intended to work?

Related

Is it safe to pass a Lucene Query String directly from a user into a QueryParser?

tldr: Can I securely pass a raw query string (retrieved as a URL parameter) into a Lucene QueryParser without any added input sanitization?
I'm not a security expert, but I need some advice. As the title states, is it safe to use this controller method:
#CrossOrigin(origins = "${allowed-origin}")
#GetMapping(value = "/search/{query_string}", produces = MediaType.APPLICATION_JSON_VALUE)
public List doSearch(#PathVariable("query_string") String queryString) {
return searchQueryHandlerService.doSearch(queryString);
}
In tandem with this service method (the error handling is for testing only):
public List doSearch(String queryString) {
LOGGER.debug("Parsing query string: " + queryString);
try {
Query q = new QueryParser(null, standardAnalyzer).parse(queryString);
FullTextEntityManager manager = Search.getFullTextEntityManager(entityManager);
FullTextQuery fullTextQuery = manager.createFullTextQuery(q, Poem.class, Book.class, Section.class);
return fullTextQuery.getResultList();
} catch (ParseException e) {
LOGGER.error(e);
return Collections.emptyList();
}
}
With only basic input sanitization? If this isn't safe are there measures I can take to make it safe?
Any help is greatly appreciated.
I've been looking into this on and off for the last few weeks and I cannot find any reason why it wouldn't be safe, but It's such an obscure question (in an area I'm unfamiliar with) that I may be missing some obvious, fundamental problem anyone working in the area would see immediately.
A FullTextQuery is always read only, so you don't have to be concerned with people dropping tables or similar issues that you might have to consider when dealing with SQL injection.
But you might want to be careful if you have security restrictions on what data can be seen by your users.
The API also restricts the operation to a certain set of indexes - in your case those containing the Poem entities - so it's also not possible to break out of the chosen indexes.
But you need to consider:
is it ok if the user is able to somehow find a different Poem than what you expected them to look for
if you share the same index with other entities, there might be some ways to infer data about these other entities
So to be security conscious you might want to:
each entity type gets indexed into its own index (which is the default).
enable some FullTextFilter to restrict the user query based on your custom rules.
actually check the content of each result before rendering it, so to remove content that your other filters didn't catch.
If you are extremely paranoid, consider that any full-text index can actually reveal a bit about how frequent certain terms are in the whole index. People are normally not too concerned about this as it's extremely hard to take advantage of, and only minimal clues about the data distribution are revealed.
So back at your example, if this index just contains poems and you're ok with allowing any user to see any poem you have stored, giving away clues about which poems you are making available is normally not a security concern but is rather the whole point of your service.

Accessing dynamic links in the format of domain.com/<dynamic_page_name> in CodeIgniter

I am using code Igniter for my PHP project. I want to give provision in my site such that users can create new pages of their own, and access them directly from domain.com/their_page_name.
But, my developers have raised a concern that, 1000's of dynamic links that are presented in the format of domain.com/ is "not good for site's performance". For some 10-15 pages, it is fine. But, beyond that, it would effect the site's performance.
So, they proposed that the URL format should be like www.domain.com/something/page_name (here, 'something' is the controller name, as they mentioned it)
But, I really can't sacrifice my framework nor my requirement.
Is there any way that I can achieve the format of "www.domain.com/page_name" without effecting the site's performance?
Thanks in advance.
No issues on
Www.domain.com\userpagename.
It's not a framework issues. Codeigniter support this type of URL.you can create n no of URL.
Performance will matter how you are handling that particular controller or that particular function.
If may be 10 may be 100 ,work around same way.
You just have to put route accordingly.
$route[default_controller]=userurl;
$route[userurl/(:any)]=userurl yourfunction/$1`;
What it seems you need is dynamic controller, which can be done using Codeigniter's build in function _remap().
A code example is:
public function _remap($method){
if($method != null){
$this->yourFunction($method);
} else {
// handle the error as you like
}
}
public function yourFunction($key){
// your code logic here
}
All this code block goes inside your controller.
Edit: the performance is exactlu the same as going with domain.com/controller/method. What it matters, as stated above, is how you handle the data.

Grails: Setting URL mapping priorities

I sometimes come across a situation where I'm trying to set URLMappings as such:
/** -> ContentController
/static/$image/$imageNumber -> ResourcesController
Then when I visit /static/image/13 it will often hit the /** instead of the /static/*/* How do I tell Spring / Grails to rather try and match the other one first?
URL mappings are hit in the order they are declared, so put your catch all /** last.
EDIT: This answer tickled at the back of my mind, and I recalled something I read on the mailing list a while back. Back in Grails 1.1 or so, URLMappings were evaluated in the order declared. Now, however, URLMapping matching is slightly more complex. The URLMappings will try to return the best match by comparing the number of wildcards, static tokens, and finally number of constraints. You can see this in the source.
Since URL mapping order no longer matters, it must be something else (although I find listing them in rough order makes it easier to read through them). It looks like the second fragment should actually be a static token. I'd try /static/image/$imageNumber.
Turns out that Grails will go from more specific to least specific, as long as:
You don't have syntax errors in your URLMappings and
Sometimes you need to restart grails for it to correctly take effect.
"/other-test/$testname" { // Fired for "/other-test/hi-there/"
controller="test"
}
"/**" { // fired for "/something-else"
controller="test"
}

C# lock keyword, I think I'm using this wrong

I recently had a problem with multiple form posting in an ASP.NET MVC application. The situation was basically, if someone intentionally hammered the submit button, they could force data to be posted multiple times despite validation logic (both server and client side) that was intended to prohibit this. This occurred because their posts would go through before the Transaction.Commit() method could run on the initial request (this is all done in nHibernate)
The MVC ActionMethod looked kind of like this..
public ActionResult Create(ViewModelObject model)
{
if(ModelState.IsValid)
{
// ...
var member = membershipRepository.GetMember(User.Identity.Name);
// do stuff with member
// update member
}
}
There were a lot of solutions proposed, but I found the C# lock statement, and gave it a try, so I altered my code to look like this...
public ActionResult Create(ViewModelObject model)
{
if(ModelState.IsValid)
{
// ...
var member = membershipRepository.GetMember(User.Identity.Name);
lock(member) {
// do stuff with member
// update member
}
}
}
It worked! None of my testers can reproduce the bug, anymore! We've been hammering away at it for over a day and no one can find any flaw. But I'm not all that experienced with this keyword. I looked it up again to get clarification...
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock
Okay, that makes sense. Here is my question.
This was too easy
This solution seemed simple, straightforward, clear, efficient, and clean. It was way too simple. I know better than to think something that complicated has that simple a solution. So I wanted to ask more experienced programmers ...
Is there something bad going on I should be aware of?
No it's not that easy. Locking only works if the same instance is used.
This will not work:
public IActionResult Submit(MyModel model)
{
lock (model)
{
//will not block since each post generates it's own instance
}
}
Your example could work. It all depends on if second-level caching is enabled in nhibernate (and thus returning the same user instance). Note that it will not prevent anything from being posted to the database, just that each post will be saved in sequence.
Update
Another solution would be to add return false; to the submit button when it's being pressed. it will prevent the button from submitting the form multiple times.
Here is a jquery script that will fix the problem for you (it will go through all submit buttons and make sure that they will only submit once)
$(document).ready(function(){
$(':submit').click(function() {
var $this = $(this);
if ($this.hasClass('clicked')) {
alert('You have already clicked on submit, please be patient..');
return false;
}
$this.addClass('clicked');
});
});
Add it do you layout or to a javascript file.
Update2
Note that the jquery code works in most cases, but remember that any user with a little bit of programming knowledge can use for instance HttpWebRequest to spam POSTs to your web server. It's not likely, but it could happen. The point I'm making is that you should not rely on client side code to handle problems since they can be circumvented.
Yeah, it's that easy, but - there may be a performance hit. Remember that a Monitor lock restricts that code to be run by only one thread at a time. There is a new thread for each HTTP Request, so that means only one of those requests at any given time can access that code. If it's a long running procedure, or a lot of people are trying to access that part of the site at the same time - you might start to sluggish responses.
It's that easy, but be careful what object you lock on. It should be the same one for all the threads - for example, it could be a static object.
lock is syntactic sugar for a Monitor, so there is quite a bit going on under the cover.
Also, you should keep an eye out for deadlocks - they can happen when you lock on two or more objects.

Refactoring fun: dealing with complicated state

Let's say we have a web app out there that is supposed to have a user fill out a form, and then it creates a ticket in the backend workflow engine. This form is going to continue to be the portal for the customer to view what's going on. Some forms go straight to ticket creation; others have to get approved by someone else before generating a ticket, and they can also be denied. This thing sends out emails, tracks answers to the questions of the form, tracks any uploaded attachments, and also logs "updates" as various actions are made to change the state of the form.
The business logic to decide what all to do when the form is first submitted or saved is starting to get hairy and I'm looking on ways to refactor it. I've started to look at state/strategy patterns, but it seems like all the logic just needs to get lumped together in one place eventually anyway. Plus, with all the dependencies on answers/attachments/log entries, it makes it complicated to inject mocks into because it has so much that it has to track.
Here's a pseudocode-ish layout of the form object's "save" functionality, simplified down...it's starting to get nasty and I'm trying to see if I can make it cleaner somehow.
if(this.isvalid)
{
if(isNewForm && !this.needsApproval) //just created, so start up a ticket
{
CreateTicket();
}
if(!isNewForm && justApproved) //pulled from the DB earlier, and was just approved
{
CreateTicket();
}
if(!isNewForm && justDenied) //pulled from the DB earlier, and was just denied
{
this.needsApproval = false;
this.closed = true;
}
if(isNewForm)
{
SendNewFormEmail();
if(this.NeedsApproval)
{
SendNeedsApprovalEmail();
}
this.CommentEntries.Add("Request submitted.");
}
else if(justApproved)
{
SendApprovalEmail();
this.CommentEntries.Add("Request approved.");
}
else if(justDenied)
{
SendDenialEmail();
this.CommentEntries.Add("Request denied.");
}
this.Save();
this.Answers.Save();
this.Attachments.Save();
this.CommentEntries.Save();
}
I've been thinking about state machines alot lately and I found the following proposal very promising. I wish I could tell you it works really great but I have not gotten that far yet. I can tell you that it looks better than any solution I've tried to date. Here's the link.. Hierarchical State Machine
if (isNewForm) {
if (JustDenied) {
...
}
if (JustApproved) {
....
}
} else {
... not a new form ...
}
I'm not sure how your handling JustDenied, but perhaps:
switch (FormState) {
case JustApproved:
....
case JustDenied:
....
}
Its psuedo code, so hard to say if that would work. But, yes, I agree that what you posted is starting to resemble pasta.
I think this is an excellent candidate for Workflow Foundation.
Problem is not to write a complicated state machine, it's dealing with the dynamics of a business (which can also seem like pasta sometimes ;)). The rules change, code needs to be changed, and as you spotted this yourself, maintainability can easily become a nightmare here...

Resources