I have linked my project with Acumatica in Customization project editor
My solution calls the event
Performs check for Payment and execute some REST requests if the desirable payment is selected.
My question is : How to get Acumatica credentials in project ? When the event is triggered it is already have access to the system, because can check the element’s values, so maybe I can get credentials in code.
Currently I have wrote Acumatica credentials in project for requests like this
But, client can change them, or make some modifications in Acumatica, so there is must be opportunity to change them without making changes in project solution.
How can I get the credentials for REST request in project ?
Page 1 / 1
Hi @Ivan
We can achieve this by using endpoint entity Users. But still, the password is in an encrypted format. you need to write logic to decrypt and use for this.
Hope this will help you.
Hi @Ivan
We can achieve this by using endpoint entity Users. But still, the password is in an encrypted format. you need to write logic to decrypt and use for this.
Hope this will help you.
Hi, jinin
Thank you for response
I need to clarify one moment : “the password is in an encrypted format. you need to write logic to decrypt and use for this.”
By which approach the password can be decrypted ? It can be done by standard .NET tools or it must be done by specific way ?
Hi @Ivan
I didn't try this before. Can you please try with RSACryptoServiceProvider.Decrypt Method?. Since Acumatica using RSACryptoServiceProvider.
I believe by default Acumatica hashes the passwords which would mean you can’t actually get the original password(the default admin password “setup” is stored in plaintext though).
You should be able to get the current User ID using ICurrentUserInformationProvider.GetUserId() and from there you can just use Users.PK.Find(graph, userID) the Users object will have the username and the password hash.
If you have disabled password hashing(not recommended) and instead are using encryption you should be able to use IUserManagementService.GetUser(userID) to get the MembershipUser object and then call GetPassword() on that. If password hashing is enabled then it will throw an error.
I believe by default Acumatica hashes the passwords which would mean you can’t actually get the original password(the default admin password “setup” is stored in plaintext though).
You should be able to get the current User ID using ICurrentUserInformationProvider.GetUserId() and from there you can just use Users.PK.Find(graph, userID) the Users object will have the username and the password hash.
If you have disabled password hashing(not recommended) and instead are using encryption you should be able to use IUserManagementService.GetUser(userID) to get the MembershipUser object and then call GetPassword() on that. If password hashing is enabled then it will throw an error.
I believe by default Acumatica hashes the passwords which would mean you can’t actually get the original password(the default admin password “setup” is stored in plaintext though).
You should be able to get the current User ID using ICurrentUserInformationProvider.GetUserId() and from there you can just use Users.PK.Find(graph, userID) the Users object will have the username and the password hash.
If you have disabled password hashing(not recommended) and instead are using encryption you should be able to use IUserManagementService.GetUser(userID) to get the MembershipUser object and then call GetPassword() on that. If password hashing is enabled then it will throw an error.
Can you please suggest what namespace must be added in order to use ICurrentUserInformationProvider and IUserManagementService ? Intellisense does not suggest me anything.
Hi @Ivan
I didn't try this before. Can you please try with RSACryptoServiceProvider.Decrypt Method?. Since Acumatica using RSACryptoServiceProvider.
Hi, jinin
I have added Users entity to Acumatica as you suggested
but the request is unworkable
I tried to find fields named admin and password, but they are absent here
ICurrentUserInformationProvider is in the PX.Data namespace if it isn’t showing up in Intellisense you are likely on an older version, you should be able to just use PXAccess.GetUserID();
ICurrentUserInformationProvider is in the PX.Data namespace if it isn’t showing up in Intellisense you are likely on an older version, you should be able to just use PXAccess.GetUserID();
I added PX,Data . Now the types are available for usage
However the last string receive the error
It required PX.Export
After I added it to project the error was removed
After I started project I received this error : Can't restore password for MembershipPasswordFormat.Hashed password format
Hi @Ivan
I didn't try this before. Can you please try with RSACryptoServiceProvider.Decrypt Method?. Since Acumatica using RSACryptoServiceProvider.
Hi, jinin
I have added Users entity to Acumatica as you suggested
but the request is unworkable
I tried to find fields named admin and password, but they are absent here
HI @Ivan
select User Information object 2. you will get the fields Login and password.
Yeah that is what I was saying, by default Acumatica will hash passwords(using the SHA1 algorithm I believe) and only store the hash. As such you cannot get the actual password. You can get the password hash off the Users object though: Users.PK.Find(graph, userID).
Basically if you are trying to re-use the current Acumatica username and password in an API call(assuming I am understanding you correctly) that is not an option with you current configuration. Acumatica doesn’t actually know your password in this scenario it just knows the hashed result of your password. So when you type in your password to login Acumatica performs the same hashing function on it and then compares that to the the stored hash result(in the database) to determine if it is the correct password.
You can turn off the hashing but that’s not recommended.
It sounds like you are trying to make an API call to Acumatica itself from within graph code which is probably not the best route. If you absolutely have to I would look at other API authorization methods(that don’t involve user passwords). Generally speaking though anything done through the API can be done via internal code. What is it you are trying to accomplish with the API calls?
Hi @Ivan
I didn't try this before. Can you please try with RSACryptoServiceProvider.Decrypt Method?. Since Acumatica using RSACryptoServiceProvider.
Hi, jinin
I have added Users entity to Acumatica as you suggested
but the request is unworkable
I tried to find fields named admin and password, but they are absent here
HI @Ivan
select User Information object 2. you will get the fields Login and password.
Thanks , it worked.
Is it possible to extract URL by same approach ?
Yeah that is what I was saying, by default Acumatica will hash passwords(using the SHA1 algorithm I believe) and only store the hash. As such you cannot get the actual password. You can get the password hash off the Users object though: Users.PK.Find(graph, userID).
Basically if you are trying to re-use the current Acumatica username and password in an API call(assuming I am understanding you correctly) that is not an option with you current configuration. Acumatica doesn’t actually know your password in this scenario it just knows the hashed result of your password. So when you type in your password to login Acumatica performs the same hashing function on it and then compares that to the the stored hash result(in the database) to determine if it is the correct password.
You can turn off the hashing but that’s not recommended.
It sounds like you are trying to make an API call to Acumatica itself from within graph code which is probably not the best route. If you absolutely have to I would look at other API authorization methods(that don’t involve user passwords). Generally speaking though anything done through the API can be done via internal code. What is it you are trying to accomplish with the API calls?
I need to do API calls in order to extract data from different entities. When the user saves the payment in Acumatica, my solution creates documents on local machine with this payment, invoices which are located in “Document to Apply tab and Customer entity data.”. I use API calls in order to make link between entities and provide valid data.
You understood me correctly, I need to re-use password in order to omit writing credentials inside the project, because they can be changed, that is the reason why I need to get login, password, Url and company in order to build request and make call to other entities inside the event
Hi @Ivan
I didn't try this before. Can you please try with RSACryptoServiceProvider.Decrypt Method?. Since Acumatica using RSACryptoServiceProvider.
Hi, jinin
I have added Users entity to Acumatica as you suggested
but the request is unworkable
I tried to find fields named admin and password, but they are absent here
HI @Ivan
select User Information object 2. you will get the fields Login and password.
I tried to decrypt password, by this approach
RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
where “credits” variable is the result of REST request and contains credential data
Unfortunately it gives error
The best overloaded method match for 'System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(bytev], bool)' has some invalid arguments
That can all be done via internal code and would be much more performant(and probably easier to code).
In the event handler you already have access to the payment data but if you need other records you can use BQL statements to retrieve them. If you need to create invoices or apply payments that can all be done via various graphs and methods as well.
That can all be done via internal code and would be much more performant(and probably easier to code).
In the event handler you already have access to the payment data but if you need other records you can use BQL statements to retrieve them. If you need to create invoices or apply payments that can all be done via various graphs and methods as well.
Can you please provide reference where it is shown how build such logic ?
I need to implement this for the following requests :
Acumatica Open University has an Application Development section that covers various topics, there’s also a pdf Acumatica Developer Guide.
DocumentsToApply uses the Adjustments view on the graph assuming you are in an extension graph for ARPaymentEntry you should be able to access it with Base.Adjustments.Select();, this will give you all the “DocumentToApply” for the current payment.
You can get the customer record by using Customer.PK.Find(customerID);
For the third one there are multiple ways to go about it. It seems like you are trying to find all payments(and their pending adjustments) with a certain reference number. I would just write a BQL statement and base it off of the BQL statement used in the Adjustments view(modified to take in parameters).
I would recommend going through the training as most of the above won’t make sense if you aren’t familiar with the framework.
Acumatica Open University has an Application Development section that covers various topics, there’s also a pdf Acumatica Developer Guide.
DocumentsToApply uses the Adjustments view on the graph assuming you are in an extension graph for ARPaymentEntry you should be able to access it with Base.Adjustments.Select();, this will give you all the “DocumentToApply” for the current payment.
You can get the customer record by using Customer.PK.Find(customerID);
For the third one there are multiple ways to go about it. It seems like you are trying to find all payments(and their pending adjustments) with a certain reference number. I would just write a BQL statement and base it off of the BQL statement used in the Adjustments view(modified to take in parameters).
I would recommend going through the training as most of the above won’t make sense if you aren’t familiar with the framework.
Hi markusray17
I am trying to extract elements from Base.Adjustments.Select();,
but I can’t find what must be added for StandAlone.ARRegistertAlias type
Can you please suggest what should be added to the project ?
Acumatica Open University has an Application Development section that covers various topics, there’s also a pdf Acumatica Developer Guide.
DocumentsToApply uses the Adjustments view on the graph assuming you are in an extension graph for ARPaymentEntry you should be able to access it with Base.Adjustments.Select();, this will give you all the “DocumentToApply” for the current payment.
You can get the customer record by using Customer.PK.Find(customerID);
For the third one there are multiple ways to go about it. It seems like you are trying to find all payments(and their pending adjustments) with a certain reference number. I would just write a BQL statement and base it off of the BQL statement used in the Adjustments view(modified to take in parameters).
I would recommend going through the training as most of the above won’t make sense if you aren’t familiar with the framework.
Hi markusray17
I found how to extract elements form Documents To Apply tab (I wrote about this in previous comment)
Now it remains to get the customer record. You suggested to use this : Customer.PK.Find(customerID);
It requires the graph parameter
I do not know what must be putted here. I can create just object of this type and put it here or it must be initialized and contain some specific data ?
That's why I was suggesting going through the training, you are going to have a lot of questions like that and this thread is going to get very long.
Graphs are business logic controllers in Acumatica, you are within an extension of a graph meaning you can access the base graph using the Base property on your extension. So to answer your question, you don't need to create a new graph you just need to pass in "Base"(the base graph).
That's why I was suggesting going through the training, you are going to have a lot of questions like that and this thread is going to get very long.
Graphs are business logic controllers in Acumatica, you are within an extension of a graph meaning you can access the base graph using the Base property on your extension. So to answer your question, you don't need to create a new graph you just need to pass in "Base"(the base graph).
Thank you for response
I understand that going through the training is important to omit lost of stages, but I need to finish it as soon as possible