Acumatica report authoring and single sign-on - oauth-2.0

Our users authenticate to Acumatica using OAuth2-based SSO with Google as the identity provider. They do not have passwords to access the system (we generate very long, strong passwords which are discarded as soon as SSO is set up).
I don't want to go into all the reasons why SSO is important to us. It's critical, and I'll leave it at that. SSO was a policy and business requirement for us to select Acumatica.
The Report Designer doesn't seem to support OAuth2.
Is there a way we can give users the ability to download the RPX files via the browser, edit them outside the browser, and then upload the changes via the browser, using only SSO credentials?
Also, where can I get the source code to Report Designer? I'd love to see if I can add OAuth2 support myself.

There are 2 types of report in Acumatica:
Standard Reports
Analytical Reports
The links above describe how you can customize these reports using Acumatica Cloud ERP.
You can notice that standard reports have the following limited customization possibility using Cloud ERP:
You can adjust the report settings to meet your specific informational
needs. For example, you can specify sorting and filtering options and
select the data by using report-specific settings—such as financial
period, ledger, and account. You can configure additional processing
settings for each report.
Analytical reports have more customization possibilities through Cloud ERP:
The Analytical Report Manager is a web-based tool for creating and
modifying analytical reports. Users can design and run custom
analytical reports using advanced data selection criteria, data
calculation rules, and customizable report layout design features. By
using the Analytical Report Manager, you can: Create the layout and
structure of reports based on your business requirements. Define data
selection criteria for the report with a high level of granularity.
For example, data sources can include a range of accounts,
subaccounts, and financial periods. Use advanced formulas to calculate
values based on the information extracted from the data source. Create
consolidated reports based on the data from multiple data sources or
other analytical reports. Localize data used by a report if
multilingual support of user input is enabled.
Acumatica marketing material shouldn't refer to the standard report editor (Windows Form Desktop Application) as part of the Cloud ERP product. The reason for this is quite simple, a Windows Desktop application is not a cloud product, it can't be accessed with a browser and is not supported on unix/apple OS.
Analytical reports designer support SSO OAuth since the designer is running on the Cloud ERP product.
Standard reports designer doesn't support OAuth. You could fill a feature request for it though. Our marketing material should not refer to standard report customization as part of the Cloud ERP product because the designer requirements are different.
We strive to make every feature available on Cloud ERP platform. At the moment these are the features not available on Cloud ERP to my knowledge:
Standard Report Editor
DeviceHub, this is a Windows program that acts like a device
spooler so you can access windows desktop hardware like printer
and scales from the Cloud ERP.
Login page customization, this can't be achieved through
Customization Project Editor, you have to change files manually on
the server.
From now on, I'll focus on the Standard Report Designer, the Windows Desktop Application.
The designer uses the Web Service API to communicate with Acumatica Database.
Besides loading and saving RPX files the report designer also uses the Web Service API for features in 'File->Build Schema' dialog like 'Load Schema'. If your user are not using the 'Build Schema' features then having only the RPX file locally should be enough to allow them to modify the report using the designer.
Code for loading and saving RPX files is located in PX.Reports.Design.ReportUtils class which is part of PX.Reports.Design.dll assembly. It's using the SOAP API which to my knowledge is not the preferred API to use OAuth, the REST Contract API is recommended for OAuth enabled Web Services. Refactoring the PX.Reports.Design.dll assembly to use REST Contract API instead of SOAP API isn't trivial.
That said I believe it's possible to load and save RPX files using the Rest API and you could write a wrapper for the report designer to handle that task as long as you forgo 'Build Schema' feature. I'll touch on that at the end of my answer.
You can find the documentation for using OAuth with Rest API here
There are two ways you can use Acumatica Web Service, attended or unattended.
Attended use requires a user to enter his credentials in some form of UI before using the web service. The report designer uses this form of authentication.
The alternative for unattended use is to configure and save the authentication credentials before using the web service. That way an automated program can use web service API without requiring a user sitting in front of the computer.
Unattended use typically doesn't involve OAuth because you can't have a user dedicated to the task of authenticating. For example, if you integrate Acumatica with an ecommerce provider, requiring him to use OAuth authorization to push the orders to Acumatica is problematic because that process usually doesn't involve a UI where a user sitting at the computer provide authorization.
You could technically create a OAuth access token that never (rarely) expires for this task but it circumvents the purpose of OAuth which is having temporary access tokens to mitigate man in the middle attacks. Certifications that mandates use of OAuth typically forbid use of tokens that never expire. That's why requesting OAuth for automated process can raise eyebrows and lead programmers to question your security policies.
Now let's get to possible solutions for your problem. You'll have to assess whether your security policies allows use of unattended web service without OAuth authorization. If that's the case then your job will be much easier. If not then you'll likely run into similar problems later on if dealing with third party web service integration for Acumatica is required.
In order to write a wrapper over the report designer you'll have to write a windows desktop application and have the '.RPS' file type associated with your wrapper instead of being associated with Acumatica report designer.
When a user clicks the EDIT REPORT button on the website, a '.RPS' text file is generated in memory on the server and the user browser is redirected to that file in order to download it locally. When the user clicks on the RPS file, windows launches the associated program (Acumatica report designer) and passes the RPS file path by command line parameter. The report designer then presents the authorization dialog where user can enter his credentials and the report RPX file is downloaded by the Web Service API.
Example of the content of an RPS file:
ServiceUrl|http://localhost/AcumaticaInstance/
ReportName|gl633000.rpx
User|admin
The idea is to have your wrapper parse this RPS file, download the associated RPX file using the Web Service API that comply with your security policy and then launch Acumatica report designer for this RPX file using command line parameter:
"c:\...\ReportDesigner.exe" "c:\...'gl633000.rpx"
When you launch the report designer you want to halt your main thread until the user closes the report designer. Framework methods that do this are typically named 'wait for exit'. Before closing the report designer the user would save the RPX file. After the designer is closed your main thread will resume and you can then re-upload that RPX file to Acumatica database using Web Service API.
The easy way would be to create a report designer user to use Web Service API in unattended mode. You could store those credentials locally (in encrypted form) wherever you see fit and never expose them in UI. When making Web Service call you decrypt those credentials on the fly. In such a scenario the asset to protect is the decryption key.
If use of attended web service is required for OAuth support you will need to implement a UI to get those credentials. If you have to use Google login page for entering the credentials you would have to include an embedded browser in your wrapper for that purpose.
As a remainder, note that this solution will enable you to modify the report definition in the RPX file but will not enable you to use report designer features that require web service API like 'Build Schema'.

Related

How to pass parameter from Asp.net application to Power BI

We are having multi tenant web application designed in asp.net mvc. Our database is stored on Azure. We have created security policy in the database so no client can see data of another client, and in every table we have tenant id for each entry.
We have created some dashboards using power bi, data is being accessed using sql stored procedure which has tenant id parameter.for testing purpose i supply tenant id while running dashboards inside power bi desktop. Now we are trying to integrate those dashboards to our web application. for this we have done necessary changes in the web.config file.
Issue is how will we supply tenantID for which user is logged in to power bi so that user can see data for that particular client only?
Thanks in advance.
It depends on the storage mode of your report (Imported or DirectQuery) and how it will be integrated in your app (Embedded API, Publish to web (public) or Secure embed).
If the storage mode is Imported, this means that your report contains a copy of the data. The consequence is that you can't query the database and get the data based on the current user, because the copy of the data is one and it is shared with all users, which are looking at your report. So the data should be for all tenants and you must filter it in each users session. The filtering can be made in two ways - by adding a "normal" report level filter or by implementing Row-level security (RLS).
Filtering can be achieved by passing the filter in the URL or defining the filter in the embedded configuration. First one can be used with Secure embed, while the later one is applicable when using Embedded API. Note, that Publish to web method doesn't support URL filters. Important part is that the filter added this way will be visible in the Filters pane and the user can modify it or remove it (so it's not a good way to secure your data). If you are embedding the report using the API, you can hide the Filters pane by setting filterPaneEnabled: false in the embed config, but this will also hide all other filters and the end user will be able to slice the data only with the visuals provided by you (e.g. slicers in the report). Also note, that secure embed requires each of the viewers of your report to have Power BI Pro license
(or if the workspace where you publish the report has a dedicated capacity assigned, i.e. Power BI Premium or Power BI Embedded, a Power BI Free license).
With RLS, you will include all the data for all tenants in your report, and Power BI will filter it for you, so the user will see only the data relevant for his tenant. This can be made it two ways - define a role for each tenant and include your end users in the corresponding role, or use userprincipalname() DAX function in your report to filter the data based on the current user.
My recommendation is to use RLS, and the benefit in this case is that there will be a single report to embed and no parameters needs to be passed to it from your app at all.

Is 'Word as a Service' possible via MS Graph API?

I have found some, but not all, pieces of the puzzle.
Using Graph APIs, when a user selects a document in my own web application, I can:-
Create a new temporary folder in their OneDrive account
Upload my.docx file to this location
Get the url for my.docx
Open the URL in a new tab, loading Office 365's MSWord editor (or viewer and editor after one more click)
This is where it gets a bit trickier. How can I get the edited content back into the location where my web application historically stored these documents?
Theorising, I can:-
Create a webhook subscription to the new folder I create
Implement a webhook listener (and validation) service
When the listener receives an 'update' notice for the document:-
Call the download(content) API, or from the driveItem metadata, download it from #microsoft.graph.downloadUrl
Persist it to my desired location within my web application
To me this sounds like it'll suffer from big delays. The webhook subscriptions typically send batches of changes and the frequency looks uncertain. It certainly wouldn't be great for versioning every individual save operation during the editing session.
Have I missed some more obvious path to Word as a Service? i.e. another API or a mixture of APIs?
Alternatives I've considered but haven't yet scoped: implement WOPI or WebDav within my own web application.
It sounds like you're only using OneDrive to take advantage of its built-in support for the MS-WOPI protocol. WOPI is basically an enhanced WebDav interface that is used by Office to work with remote document (i.e. files stored on OneDrive, Box, DropBox, etc.).
Your solution is generally fine and it is certainly easy enough to orchestrate. You can absolutely use webhooks to subscribe to changes to the file. You'll likely want some mechanism in your app to notify your system when they're "done" so you can clean up the file afterwards.
If you want a more robust solution, you'll need to look at WOPI. Implementing WOPI would allow you to keep these files on your system permanently. Office Online would use the WOPI interface to speak with your storage system and open/save/edit files in-place.
Keep in mind that implementing WOPI (or any protocol for that matter) is often a non-trivial endeavor. You will also need to get your final solution validated and whitelisted by Office before it can be used. Details on this process and how to request access can be found at the Microsoft Cloud Storage Provider Program website.
Today OneNote and Excel are the only office "document clients" that have API's exposed via a REST API publicly available in the Microsoft Graph.
The only other "publicly available options" I'm aware of are:
WOPI APIs, that kind of act like a REST API but muche older
The office add-in model (hosted in a client) with the JavaScript API
The word object library (old, relying on dcoms and needs to have office installed and licensed on the machine)

iOS - use Aceess database and sharepoint to push and pull data

Currently I am creating app that needs to store and pull data from database by multiple users.
Since I do not have much knowledge in database, MS Access, and MS Sharepoint, I would like to know if it is possible to use share point as database for my iOS application, which implemented in pure swift code.
Any one with knowledge in this field please help me by providing advice on if it works, and, if possible, how can I successfully implement this.
Thank you for all the helps.
I don’t see why this would not work. As long as the SharePoint tables follow the rules for Access, then you can place the ms-access application on each desktop. Anytime “any” user of that application updates or adds records, then all other users will “eventually” see the updates. So in this setup, the desktop users can in fact “run” the application “off line”. The instant such users get Wi-Fi or a connection (or always have one), then the data is synced in real time.
The above setup takes no coding and is part of the Access system which supports those SharePoint tables.
As for the iOS and that part of the application? Again, I see little problem since all of the abilities of SharePoint are available as a web service. So as long as your development platform supports standard web services, then your application can interact with that web service to retrieve and update rows of data in those SharePoint tables. As noted, the “sync” to the Access clients will thus reflect any updates to that data.
Since near every modern phone development system supports interaction with web services, then the phone software can do the same. You not have an ODBC like interface, but you can query the data (CAMEL).
The Access desktop client will also be interacting with the SharePoint tables via a web service, but from Access point of view the SharePoint tables (lists) look like any regular SQL like table. So standard VBA code and DAO reocrdsets are supported.
The web services for SharePoint are outlined here:
https://msdn.microsoft.com/en-us/library/ms479390(v=office.12).aspx
And this video shows how you can upload data to SharePoint from Access, and NOTE how the relational table ability of SharePoint is supported by Access. Once that data is uploaded, then Access supports updating of such data as if the data was a local table.
https://www.youtube.com/watch?v=3wdjYIby_b0&list=PL27E956A1537FE1C5&index=2
You can use a single office 365 account at $6 per month for the above, and that single account supports 500 free users. So if you don’t have SharePoint (or don’t want to bother with SharePoint, a single office 365 account also offers these SharePoint services for that one stupid low price of $6 per month – and that account with work with the free Access runtime that that you can use to run the Access side for free on the desktop part of this application.

Box.com Service Account access

All box.com's api's read to require OAuth 2.0 using only Authorization Token grant types. I have a back end system that needs to upload a file to a box.com system. However, I do not understand how a back end system is suppose to integrate, when the authorization flow requires user "approval" to get a token.
Anyone ever done this? I am attempting to integrate a java mule app. I attempted to use the components, but they plain do not work at all, they break the entire anypoint studio. Now I am trying to utilize the http component to make the call but I am losing my patience with it.
please help, I am pretty much ready to drop kick this laptop and live in the woods.
Integration with public online API requires a little study, a little coding, and a little testing. I'm not saying it's easy. Take a look here at a Mule component I've recently created that communicates with Toggl, an online timekeeping service.
https://github.com/ciwise/toggl-api-connector
Your question requires a lot of discussion but it's best answered with example. If Box does not provide a Mule component, you can create one yourself.
The HTTP connector is not going to authenticate or perform any operations at Box for you. The HTTP connector provides the HTTP endpoint (URL entry and browser return). To authenticate your application with Box and call API operations, you'll need to do some work.
This is the high-level recipe for my solution with Toggl service (example)
Update your Anypoint Studio with Mule Connector DevKit software
Create an Anypoint Connector project in Anypoint Studio (Eclipse)
My connector provides multiple methods to process and these are used with different instances of the component (connector) in my use flow.
My TogglDataAPIHandler.java makes various checks to see if the application (Mule) is authenticated before making calls to the Application Programming Interface (API). The API is provided by Box so that developers (people writing code) can communicate with the service outside of the web browser. There's no simple answer here. You will have to do some coding. My component/connector is only an example of one way to do this (communicate programmatically with the API).
Build and install the connector(component) locally so that we can see it in the Mule Design Palette.
Drag as many of our new component (Anypoint connector) as needed into our flow canvas.
Test the flow.
I hope that helps. Take a look at my Github repo and Mule Connector. There's a wealth of information in anyone's code. But, integration with an API requires code. You can also search the Exchange for a Box connector. If you find one, then your life is simpler. You still need to read this thoroughly:
https://docs.box.com/docs

Using OAuth in free/open source software

I'm now reading some introduction materials about OAuth, having the idea to use it in a free software.
And I read this:
The consumer secret must never be
revealed to anyone. DO NOT include it
in any requests, show it in any code
samples (including open source) or in
any way reveal it.
If I am writing a free client for a specific website using OAuth, then I have to include the consumer secret in the source code, otherwise making from source would make the software unusable. However, as it is said, the secret should not be release along with the source.
I completely understand the security considerations, but, how can I solve this dilemma, and use OAuth in free software?
I thought of using an external website as a proxy for authentication, but this is very much complicated. Do you have better ideas?
Edit:
Some clients like Gwibber also use OAuth, but I haven't checked its code.
I'm not sure I get the problem, can't you develop the code as open source retrieve the customer secret from a configuration file or maybe leave it in a special table in the database? That way the code will not contain the customer secret (and as such will be "shareable" as open source), but the customer secret will still be accessible to the application.
Maybe having some more details on the intended platform would help, as in some (I'm thinking tomcat right now) parameters such as this one can be included in server configuration files.
If it's PHP, I know a case of an open source project (Moodle), that keeps a php (config.php) file containing definitions of all important configurations, and references this file from all pages to get the definition. It is the responsibility of the administrator to complete the contents of this file with the values particular to that installation. In fact, if the application sees that the file is missing (usually on the first access to the site) it will redirect to a wizard where the administrator can fill the contents in a more user friendly way. In this case the customer secret will be one of these configurations, and as such will be present in the "production" code, but not in the "distributable" form of the code.
I personally like the idea of storing that value in the database in a table designed for it and possibly other parameters as the code needs not be changed. Maybe a installation wizard can be presented here ass well in the case the values do not exist.
Does this solve your problem?
If your service provider is a webapp, your server needs consumer signup pages that provides the consumer secret as the user signs up their consumer. This is the same process Twitter applications go through. Try signing up there and look at their workflow, you'll have all the steps.
If your software is peer-to-peer, each application needs to be both a service provider and a consumer. The Jira and Confluence use cases below outline that instance.
In one of my comments, I mention https://twitter.com/apps/new as the location of where Twitter app developers generate a consumer secret. How you would make such a page depends on the system architecture. If all the consumers will be talking to one server, that one server will have to have a page like https://twitter.com/apps/new. If there are multiple servers (i.e. federations of clients), each federation will need one server with this page.
Another example to consider is how Atlassian apps use OAuth. They are peer-to-peer. Setting up Jira and Confluence to talk to one another still has a setup page in each app, but it is nowhere near as complex as https://twitter.com/apps/new. Both apps are consumers and service providers at the same time. Visiting the setup in each app allows that app to be set up as a service provider with a one-way trust on the other app, as consumer. To make a two-way trust, the user must visit both app's service provider setup page and tell it the URL of the other app.

Resources