Thursday, May 12, 2022

#910 OIC May 22 Release New Features



Get the intel here

Thursday, May 5, 2022

#909 OIC May 22 release New Features - QuickBooks Adapter

 








This adapter augments our already rich set of ERP adapters. QuickBooks, according to Wikipedia, is "an accounting software package developed and marketed by Intuit. First introduced in 1983, QuickBooks products are geared mainly toward small and medium-sized businesses". 

This first release of the adapter will support Create, Retrieve, Update and Delete operations on the publicly exposed QuickBooks business objects. For example - create account, retrieve bill, update customer payment, delete invoice etc.

Creating the QuickBooks connection in OIC

 












As you can see, the QuickBooks Adapter connection page requires client id and client secret for establishing the connection to QuickBooks application. Please note, the scope, com.intuit.quickbooks.accounting, is added by default, if you do not provide any value in this field.

You will need an Intuit Developer's Account in order to generate client id and secret.


Leveraging the QuickBooks Connection in an Integration





 



I want to create a customer, so my REST trigger request payload is as follows - 























{
  "companyName" : "Hare of the Dog Pub",
  "contactEmail" : "dominic@hotd.ie",
  "suffix" : "Jr",
  "title" : "Mr",
  "firstName" : "Dominic",
  "middleName" : "Bart",
  "notes" : "Here are other details",
  "lastName" : "Kennedy",
  "contactPhone" : "(555) 555-5555",
  "companyAddress" : {
    "state" : "CA",
    "city" : "Mountain View",
    "zip" : "94042",
    "addressLine1" : "123 Main Street",
    "country" : "USA"
  }
}

Response Payload is as follows - 














The QuickBooks invoke mapping is as follows - 










The Response mapping - 






Let's try it out!

























Retrieve Customer from QuickBooks

So here is a new integration that retrieves a customer, based on id.
The REST Trigger has one request parameter - custId.

The QuickBooks invoke is configured as follows -



















Invoke Mapping - 




I complete the integration response mapping, activate and test -

























I am a total neophyte in respect to integrating with QuickBooks, so I started by looking at their api docs, available here.













Summary

Net, net, this adapter greatly simplifies integrating with Quickbooks. Hope you get the opportunity to try it out soon! 

















Tuesday, April 26, 2022

#908 OIC & OAuth 2.0 - Part 3

In this final post on this theme, I will discuss the authorizer function, that will validate the client token and invoke IDCS to generate a new OIC token. This function will be called from API Gateway, which takes the result and injects the new token into the Authorization Header, before routing the request to OIC. The latter will then be injected into the original request, which is then forwarded to OIC.












An introduction to the authorization function can be found here in the API Gateway docs.

Net, net, the code will be written in python, and there are examples already available, thanks to some of my Oracle colleagues. In fact there are how to's already available out there on OIC and OAuth, however, sometimes details are missing. And, as you all know, the devil lies in the detail. This series of posts has been written with neophytes in mind, i.e. my audience are not expected to be experts in IDCS, OCI Functions etc.- simply folks who need to protect their public facing OIC endpoints. I got a great deal of help from my colleagues so - 

A big thank you here to Valeria Chiran and Robert Wunderlich!

Let the show begin...

IDCS Configuration

I begin by creating the OIC app in IDCS - 




 







I also create an app, to be used for validating the client token - it is configured as follows - 
















I can try the introspection invoke in Postman - 
The default IDCS IRL is - 
https://yourIDCS/oauth2/v1/introspect

Here is the invoke is Postman -

Firstly, I get a token for the admin -










Then I use it as follows - set token to new access token value.













The introspect request uses Basic Auth (user/pwd set to clientId / secret)















This is the client id and secret from the IDCS App - AA-Salary-application-introspection.
 

OCI Vault

This is used to securely store the client secrets -











Pre-requisite IDCS Policies

We have here api gateway invoking functions, functions invoking OCI Vault etc.So we need to apply some policies so this will work.

I create the following policy at root level -


 
 


The following policies were created in my compartment containing api gateway etc. -






apiGtyVaultPolicy - 

Allow any-user to use secret-family in compartment yourCompartment where ALL {request.principal.type = 'ApiGateway', request.resource.compartment.id = 'yourCompartmentOCID'}

Allow any-user to use secret-family in compartment yourCompartment where ALL {request.principal.type = 'fnfunc', request.resource.compartment.id = 'yourCompartmentOCID'}

fnVCNPolicy -

Allow service FaaS to use virtual-network-family in compartment yourCompartment

APIGtwyFnPolicy -

ALLOW any-user to use functions-family in compartment yourCompartment where ALL {request.principal.type = 'ApiGateway', request.resource.compartment.id = 'yourCompartmentOCID'}


Creating the Authorizer Function

This will essentially do what we have already tested in Postman.

To re-iterate, the function will do the following -
1. validate the incoming client token via IDCS
2. If token is valid then get a new access token for OIC from IDCS.
3. Function Configuration keys will be created for variables such as client ids, secrets, introspection url etc. The secrets will be stored in OCI Vault, so the variables will contain the ocids of those secrets.  

Again, a big thanks to my colleague Valeria Chiran for the function code.

The code is available on gitHub -













The main authorizer code is in func.py
ociVault.py gets/decrypts the secrets.

requirements.txt lists the required libraries.

So let's create the function -
 




cmd to create python function is as follows -
fn init --runtime python myCustomAuthorizer4OIC

Check out what's been generated -




Copy and paste the func.py code -









Notice the use of context variables - this refers to the Function Configuration keys, mentioned earlier.
Create a new file ociVault.py e.g. nano ociVault.py
Copy and paste the code from ociVault.py 

Ensure the requirements.txt contains the following entries -




 




Deploy the Function - 
fn -v deploy --app apiGtwyCustomAuthorizer

wait for the Successfully created message.



























Back to the context variables - you can go thru the code and pick these out. However, here they are -














idcs_introspection_endpoint
apigw_idcs_app_client_id
apigw_idcs_app_client_secret_ocid
idcs_token_endpoint
oic_idcs_app_client_id
oic_idcs_app_client_secret_ocid
oic_scope

These are mainly self-explanatory, but, just in case -

The idcs_introspection_endpoint is called to validate the original client token that is passed to api gateway.

The apigw_cs_app_client_id and apigw_cs_app_client_secret_ocid refer to the client id and secret of the IDCS App - AA-Salary-application-introspection.

The oic_idcs_app_client_id and oic_idcs_app_client_secret_ocid refer to the client id and secret of the IDCS App - AA-Salary-application-OIC.

The idcs_token_endpoint is called to generate the OIC access token. 

We can test the function in the CLI, all we need is a valid token - this we can generate from Postman -



















echo -n '{"token":"Bearer token"}' | fn invoke apiGtwyCustomAuthorizer mycustomauthorizer4oic | jq .

The result - 














great - so that's working, now to invoking the function from API Gateway.

Configure API Gateway to invoke custom authorizer 

I amend the OIC_AA_SALARY_ADMINS deployment as follows - 




































That's the function invoked, now to swapping the token - 















Value is set to ${request.auth[back_end_token]}

Now let's test this - and there it is - the response from OIC -






















Let's check out the logs

Function logs - 















API Gateway logs -