Default Definer Rights in Method Definition - security

In Checkmarx report, I'm getting the below:
Default Definer Rights in Method Definition.
It has highlighted a case statement(shown beow)
case when v_risk='RISK' then 'Y' else 'N'
Please let me know what the issue is and what needs to be done to resolve this?
Note: authid current_user is already added in the package.

This finding can be solved by adding AUTHID CURRENT_USER clause in your procedure or function where your case statement is in
create or replace procedure sample_procedure
authid current_user
as
begin
...
case when v_risk='RISK' then 'Y' else 'N'

Related

Access document when I have the UID

I have a combobox on my form that loads client names from a view using the format "name | UID" - this displays the client name on the form but saves the UID in the field.
I now want to use the UID to lookup the name for the client and save it in a field on the XPage that is not visible using the following code:
// ignore when UID is null
if (getComponent("parentUID").getValue() == null)
return false;
var UID:string = getComponent("parentUID").getValue();
var doc:NotesDocument = database.getDocumentByUNID(UID);
// now set your fields
document1.setValue("nachname", doc.getItemValueString ("nachname"));
document1.setValue("vorname", doc.getItemValueString ("vorname"));
I do this in a simple action attached to a button. The next simple action is a Save.
The code crashes with the following error:
Error while executing JavaScript action expression
Script interpreter error, line=8, col=42: [TypeError] Exception occurred calling method NotesDatabase.getDocumentByUNID(java.lang.String) null
I have copied the parentUID to a field on the document and I am getting the correct UID and the document exists in the database?
Any ideas?
PS: I am adding this to an existing application and the current document is not a response document - cannot change that unfortunately :o(
OK, I have found my problem - XPages returned the UID but it included a leading space. When I concatenated the values I did the following: "name | UID" i.e. I added a leading and trailing space to the pipe symbol to make the code legible - this was causing the problems.
It looks like you are missing the get.Value() in your getComponent line
Try getComponent("parentUID").getValue() == null
My guess is that this is causing the code to run when the UID is null. This means that the code is running when it really is null, and your effort to check for that isn't working.
Thanks for checking that.
Can you put in a print() statement and ensure that you have a value in the var UID.
Another thing, please capitalize the word "String" since java classes are capitalized.

Validate value in field

Is there anyway to check when you type in to a field if there already are any document saved with that value in that field. Ex, if you type projectno i want to check if any other document already have that projectno. Any suggestion how i will validate that
Regards
You need a view in the database that is sorted in the first column by the field that you are using. I will assume it is a hidden view, called "(lookupUnique)". Build it and test it to make sure it is showing the field that you want in the first column, and that the values are sorted.
Now you need a way to do a lookup into this view. Ideally, you're wanting the lookup to fail -- because there is no document with the same value, in which case you allow the save to continue. But there's one other case where you might want to allow the save to continue. That's the case where the lookup succeeds because the lookup found the document that you are working on right now, which was previously saved and therefore is found in the view, and a user is now editing it again.
The #DbLookup function with the [RETURNDOCUMENTUNIQUEID] and [FAILSILENT] arguments is the IBM-recommended solution for this. I.e.,
foundId := #DbLookup("Notes":"NoCache";"":"";"(lookupUniqe)";theUniqueFieldNameGoesHereWithoutQuotes;1;[RETURNDOCUMENTUNIQUEID]);
If this formula returns "", then no match was found, therefore your code should return #Success to let the save continue. If it returns anything else, then compare the result with #DocumentUniqueId. If they match, then your code should return #Success to let the save continue. If they do not match, then you have found another document with the same value in the field, so your code should return #Failure with an appropriate error message.
Now here's the caveat: there have been known problems with [RETURNDOCUMENTUNIQUEID] in some versions of Domino, including a bug that caused Domino 6 servers to crash if an agent called ComputeWithForm on a document based on a form that used this feature. There's also a bug that causes it to return only the unid of the first match out of many matches, and so if you have duplicates this strategy in your code will allow users to re-save old documents that are already non-unique instead of forcing them to change them to make them unique, and that may or may not be what you want.
If either of those known issues might create a problem for you, then you would be better off not using [RETURNDOCUMENTUNIQUEID], and instead just do what Notes and Domino programmers did before IBM added the [RETURNDOCUMENTUNIQUEID] option in the first place: add another column to your (lookupUnique) view, and set the column value to #Text(#DocumentUniqueId). Change the 1 in the above #DbLookup formula to the number of the column that you added, and write your validation code to anticipate the possibility that you might get back an empty string, a single value, or a list of values.
If a type 45678 i return a value because there already are a document with that value. I don’t understan how i will validate it.
var dbname = session.getServerName() + "!!" + "proj\\webno.nsf";
getFieldValue = getComponent("oNo").getValue();
tmp = #DbLookup(dbname, "(webNo)", getFieldValue, ”obNo”);
if (tmp == getFieldValue)
{
Here i will do a validate. If value i return are the same as in the getFieldValue
and tmp or just getFieldValue is empty.
}
else
{
Here is it OK
}
Taking your code and modifying it. Assuming we're in the database we're creating the document in, just use #DbName() instead of trying to build the name from the session and some hard-coding. When using validation, the value of the control should be accessible simply with value. Then, just get all the values in the column and see if your value is in there.
I think the following should work.
<xp:inputText id="projectNumber" value="#{doc.ProjectNumber}">
<xp:this.validators>
<xp:validateExpression message="Value already in use">
<xp:this.expression><!CDATA[#{javascript:var usedValues = #DbColumn(#DbName(), "(webNo)", 1);
if ( #IsMember ( value, usedValues ) ) { return false };
return true;
</xp:this.expression>
</xp:validateExpression>
</xp:this.validators>
</xp:inputText>
Why don't you just generate a value for them? The simplest would be to use #Unique, but there are plenty of other ways besides having them have to create one.....

How to make #DbLookup in XPages verify the existence of a value in another database?

I have an XPage that is doing an #DbLookup with a user's input and trying to find that value in a view in a different database yet on the same server.
I have already verified that the view is in fact sorted by the first column and therefore #DbLookup friendly. The following code below appears in the server-side Javascript OnClick event handler for a button on my XPage.
My problem is that the an error occurs when trying to assign the value of lRep to the 'firstNameLabel'. lRep is returning a null value from the dbLookup even though the a record under the 'FirstName' field exists with the key 'P301993'. This dbLookup should be finding a returning a single 'FirstName' result. However, it is not.
var resultLabel = getComponent("firstNameLabel");
var dbName = new Array(#DbName()[0],"UKCSandbox.nsf");
var lRep = #DbLookup(dbName,"customerLookup","P301993","FirstName");
resultLabel.setValue(lRep.toString());
Unless your formatting was lost in copy and paste, your code has flaws. This is not Java, this is JavaScript. Line endings matter and functions don't act on the object, but return a value. Also #DbLookup returns a string when you have exactly one match, so checking for string doesn't help you.
Your code should look like that:
var ukcNumber = Registration.getItemValueString('UKCNumber').toUpperCase();
var resultLabel = getComponent("ukcNumberLabel");
var dbName = #DbName();
dbName[1] = "UKC\\UKCSandbox.nsf";
var lRep = #DbLookup(dbName,"customerLookup",ukcNumber,1);
resultLabel.setValue((lRep) ? "Success" : "Failed");
Does that work for you?
Update: 2 things to check:
does the lookup work in the same database using #DbName?
XPages have the same security constraints as Java agents. Do you have enough rights in the server document to do a 'get value from other database'? Default is No!
Have you tried making the dblookup work outside of xpages, i.e. with ScanEZ or in the Notes client?
Check your ukcNumber variable so it contains a value.
Edit
Check so the user has rights to do the lookup in the other database.
Also try a similar code on an old Notes Form and see if you get the same result.
Why can't you use keyword '[FAILSILENT]' in your #DBLookup call. It'll return "", if no entry matches with your key.
If you still have issues, use SSJS/java code to see where it's breaking up.

xpages validate database exist

I'm new to javascript and xpages here. I'm upgrading an old notes application to xpages. In my xpage I have a field, a save button, and an error messages control. The field is used to save the value of a nsf path/name that the user typed in to be used later on (e.g: //SAS/address.nsf). How do I validate if that path/database exist? The previous lotusscript is like this(it uses 2 field, one to get the server path, the other to get the db path. but for current xpage, the requirement is to use one field only):
svr$= source.FieldGetText("ServerPath")
dbsvr$= source.FieldGetText("DBPath")
Dim db1 As New NotesDatabase(svr$ , dbsvr$)
If Not db1.IsOpen Then
Messagebox "Cannot find the database."
Call source.GotoField("DBPath")
continue = False
Exit Sub
End If
In the field in the xpage, I've added a validateExpression validator. In the expression property, I compute the following SSJS:
var dbdir:NotesDbDirectory = session.getDbDirectory(null);
var db:NotesDatabase = dbdir.openDatabase(document1.getItemValue("dbpath"));
return db.isOpen();
In the validator's message property, I put "Cannot find database".
The error I'm keep getting is:
Expression is invalid.
Expression did not return a boolean value.
Any way to fix this? Is it the wrong use of validator? I've already test with local database and database on other server. None seems to work. All those database I tried I had access rights to them.
You should probably use sessionAsSigner in order to open the database as the signer of the XPage - instead of as anonymous (if you are not logged in). Also, consider adding try/catch around your dbdir.OpenDatabase() in order to catch errors opening a database with an invalid path.
Also, notice that the validateExpression validator must return a boolean true or false. In your case dbdir.openDatabase() will return null if the database can not be opened - which means that db.isOpen() will fail to work since it can not operate on a null object.
You could consider using the customValidator validator which must return an error message (and not a boolean true or false).
I hope this can help you complete the validation.
Use try/catch block for attempt to open database. If everything is OK, just return true in try block. Catch block will return false, what will handle most of the possible fails: wrong server, broken connection, invalid path, no access, and so on.
try {
// open database here and touch some property, doc count, for example
return true;
} catch (e) {
return false; // failed to open database
}

I do not want my updates to do an add if entity does not exist

I want to be able to provide an UPDATE method to my users that will update the record they specify based on RowKey but it will NOT ADD it if the RowKey they pass in does not exist.
My reasoning is that if they mistakenly send in an invalid RowKey, I do not want them unknowingly ending up with a new entity vs. having updated the one they intended to update in the first place.
Here is the gist of the code I have (but that Adds/inserts the entity if it does not exist):
' p below is the entity obj (Inherits from TableServiceEntity)
' PartitionKey and RowKey are set to values of entity to update
MyBase.AttachTo(_tableName, p)
MyBase.UpdateObject(p)
MyBase.SaveChangesWithRetries(Services.Client.SaveChangesWithOptions.Batch)
My issue is that I was expecting to get some exception thrown when SaveChanges executed and no entity with matching PK and RK was found. Instead the entity with the new PK, RK combination is added.
How can I structure my code so that only an UPDATE is done and no ADD if PK, RK is not existent?
I believe if you call the three argument version of AttachTo(), you will get the desired behavior.
MyBase.AttachTo(_tableName, p, "*");
But I haven't actually tried it.
Rather than catching an error when you try to update and item that doesn't exists (I believe breischl is right about how to avoid that) the easiest thing to do would be to run a query to check if it does actually exist first.

Resources