CPayment error at Asi.Utilities.Utilities.LogPciEvent. Object reference not set to an instance of an object.

We have just applied the latest patch to version iMIS 15.1.2.4730.

This has caused an issue with iBO especially the payment object. When setting the credit card, it errors out at:

System.NullReferenceException: Object reference not set to an instance of an object.
at Asi.Utilities.Utilities.LogPciEvent(String eventType, Int32 originationCode, Boolean result, String decryptedValue, String encryptedValue)
at Asi.iBO.CCrypto.Encrypt(String clear)
at Asi.iBO.Financials.CPayment.set_CreditCardNumber(String value)

Is this something that has been added in the new version of iBO?

The error occurs at

string userId = AppPrincipal.CurrentIdentity.UserId;

Now we are using iBO in a WCF webservice which is consumed by a silverlight application. It seems that the AppPrincipal.CurrentIdentity is null since it is not running in an iMIS application context or WCM context.
So is iBO not supposed to run outside of the iMIS application context? or is this a bug?

Thanks
Nasser

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

How is your code logging into iBO.NET? (if at all)

The App identity is null, and it shouldn't be.  (See http://www.imiscommunity.com/using_ibo ).  I realize your app worked prior to the patch, but I don't think this is really a bug - it's more that the path your app followed avoided any checks for a non-null App identity. 

Hi Henry, This is the line

Hi Henry,

This is the line that results in a null value:

<code>
return (Thread.CurrentPrincipal as AppPrincipal);
</code>

As far as my application is concerned, it has the right connection string and all other aspects of iBO work as expected. It is when I process payment, iBO tries to log pci event (Which it never used to before), which then results in that error. a WCF webservice is stateless. It has no concept of who the current logged in user is. It is only aware of the user context that IIS or the IIS apppool is running in.

The log pci event inserts a log entry in the database about the credit card payment being made. It tries to figure out who the user is that is trying to make the payment and when the above code is called, it results in  a null value.

Regardless, when an API results in an object reference not set to an instance of an object, it has to be a bug even if it means a try catch block should be implemented.

Nasser

fair enough...

... it could fail a little more gracefully, but the code is assuming the standard iBO initialization routine of iboAdmin.InitializeSystem, followed by CStaffUser.Login (or CContactUser.Login).  You should be able to resolve the problem by calling one of the login methods after you call InitializeSystem. 

I am calling

I am calling iboAdmin.InitializeSystem().

I am also calling CContactUser.LoginByWebLogin("manager", "manager");

Henry, I presume you have used iBO's before? Do you realise that I cannot even instantiate a gift object without passing an IiMISUser object.

Again, all other ibo calls are working as expected, for example: CContact contact = new CContact(user, "91045"); works as expected.

Any other thoughts apart from initialization or login or ibo usage issues?

Nasser

Something to try...

LoginByWebLogin ("manager") instead of LoginByWebLogin("manager", "manager").  It looks like there may be a bug in LoginByWebLogin(login, password), where the app principal isn't set properly.

did using the different overload...

...of LoginByWebLogin resolve the problem?

This probably affects everyone doing payments with iBO...

It appears it is sufficent just to call:
contactUser = Asi.iBO.ContactManagement.CContactUser.LoginByWebLogin(staffLoginUserId);
To get the App Principal Setup.  I call the above code, and then do what I was doing before, using a staff user.  I never end up user the contactUser in the code again.
This seems to resolve that particular issue.

Before I was just doing:
staffUser = CStaffUser.Login(staffLoginUserId, staffLoginPW);
And using staffUser everywhere

Now I do:
staffUser = CStaffUser.Login(staffLoginUserId, staffLoginPW);
contactUser = Asi.iBO.ContactManagement.CContactUser.LoginByWebLogin(staffLoginUserId);

And continue to use staffUser like before.  I don't use contactUser in my code after creating it.  But everything works.

Jason

 

 

 

 

 

 

 

Yes,

Yes, LoginByWeblogin("manager") works.

Shouldn't the other method that accepts the password be deprecated or removed, so we instantly get a compile time error instead of "Object reference...",
then spend half an hour trying to reflect the code to see what the problem is,
then try and convince someone on iMIS community that it is indeed a bug.

Some way of informing the wider community where iBO based implementations are increasing on a daily rate would be highly appreciated.

So now you can use iBO to login as manager without knowing the password. A bug or a feature. Fascinating!

Nasser

It's a feature, so that

It's a feature, so that system-level code can run without having to store a password (insecurely) anywhere. It's not a security hole because in order to run that code, someone either has to have access to add the code to your website or otherwise know the connection string to your database, at which point they can do anything they want anyway.

The overload with the password exists so that code can use iBO.NET to validate user logins. Both overloads are needed, they just are intended for different usage scenarios.

Eric Means
System Architect, ASI

How does this help with ChangeWebLogin?

I'm trying to use ChangeWebLogin to assign a username to a contact who doesn't already have one.  I can only find overloads for:

ChangeWebLogin(username, password)
ChangeWebLogin(username, authorizedUserWebLogin, authorizedUserWebPassword)

Since the person doesn't yet have a username, I rather doubt they have a password, so I don't expect the first variation to work.

The second flavor requires knowing a username and password.  I'd really like to avoid embedding a username and password in my app.

Is there a way to use the LoginByWebLogin() method so that I can assign a new username?

--
Bruce Wilson
Director, Technical Services
RSM McGladrey, Inc.

Er, that's ChangePassword()

Er, got a little mixed up there.  Let me start over.

ChangePassword has two overloads:

ChangePassword(password, newpassword)
ChangePassword(newpassword, authorizedWebUserLogin, authorizedUserPassword)

The contact I'm trying to activate has no username or password, so I don't think I can use the first form.  I can't use the second form without knowing an authorized username and their plaintext password.

I'm calling ChangePassword first, because ChangeWebLogin only has one form, which requires I know the password of the user I'm changing.

How can I assign both the username and password for a contact who doesn't have either without knowing the plaintext password of a user?

--
Bruce Wilson
Director, Technical Services
RSM McGladrey, Inc.