How does on implement Oracle Apex region authorization - oracle-apex

The bind variable :app_region_id works region however it does not work for the authorization scheme
SQL statement for region
SELECT WORKSPACE,APPLICATION_ID , PAGE_ID, REGION_ID, REGION_NAME,AUTHORIZATION_SCHEME, :app_region_id
from apex_application_page_regions
where region_id = :app_region_id
Authorisation scheme
Scheme type: Exists SQL Query
SQL Query:
Select 1
from apex_application_page_regions
where region_id = :app_region_id;
which bind variable should I use to achieve region authorization. The code that I wanted to implement, it does not return the desired results
Select 1
from AD_GRP_APEX_REGION_ASSOC r,
AD_GRP_EMP e
where e.ad_grp = r.ad_grp
and e.user_id = :app_user
and r.region_id = :app_region_id

The variable :app_region_id is not a global variable in the same way as :APP_USER. Authorization schemas only work with global variables which are associated to the SESSION, not to a element in a page ( such is a region ). Besides that, it does not make any sense to have it because you use AUTHORIZATION SCHEMAS to limit access to different components in your application. Let me show how to apply authorization schemas to regions in Oracle Apex.
Let's imagine I have a test application with three regions:
Region 1 shows one field of a query ( one row )
Region 2 shows another field of a query ( one row )
Region 3 only shows a message ( static content )
Without any authentication schema, it shows this
Now, let's create an authorization schema example that derives who is the user and based on this will show only region 3. In my case my application uses the authentication schema by default ( apex users ) so the user logged is always assigned to the global variable :APP_USER.
Application Builder --> Shared Components --> Authorization schemas
Authorization Schema --> MY_TEST
Type --> Exist SQL QUERY
select 1 from dual where exists ( select user_name from apex_workspace_apex_users where workspace_name = 'MY_WORKSPACE' and user_name = upper(':APP_USER') )
This authorisation schema will forbid to see a region when the user exists, so basically for everybody, obviously I am doing it just for testing purposes.
Then I modified attributes of REGION 1 and REGION 2 , changing the authorization schema to MY_TEST
Now, when I execute the application , I can only see the region3 in the page.

Related

NetSuite REST API with Postman: Record not found while using Suiteql

I'm trying to query some records like vendor and customer using suiteql with REST API using Postman.
The issue is that it return everytime the same error:
"Invalid search query. Detailed unprocessed description follows. Search error occurred: Record 'customer' was not found."
I tried:
differents syntax like Customer, CUSTOMER, customers, Customers, CUSTOMERS
but no change.
I added customer access to the role.
Is there something to activate while using suiteql with rest api?
Can you first try with select * from customer and see if any results are returned and then go on appending your conditions like date created greater than this year start
SELECT id, companyname, email, datecreated
FROM customer
WHERE datecreated >= BUILTIN.RELATIVE_RANGES('TFY', 'START')
AND datecreated <= BUILTIN.RELATIVE_RANGES('TFY', 'END');
NetSuite doesn't say it but for a record to be searchable, the user needs to have the following permissions:
Transactions:
Find Transaction
All the records needed
Lists:
Perform search
All the records needed
Setup:
REST WEB Services
Log in using Access Tokens or Oauth 2.0
Reports:
SuiteAnalytics WorkBook

Searching Athena AWS WAF logs by http header

I've set up AWS WAF Logging to S3, and created an Athena table as described in the documentation ( https://docs.aws.amazon.com/athena/latest/ug/waf-logs.html )
However, http headers are stored as an array<struct<name: string, value: string>> not a map (for valid reasons). I'd like to write a query like
select headers.user-agent, headers.if-none-match from waf_logs where something;
if-none-match may or may not be present in the headers list.
using CROSS JOIN UNNEST(httprequest.headers) doesn't work, as this will create multiple rows. Using map notation doesn't work, as its a array of struct, not a map.
There are a lot of pages on the internet about how to set up the table, but not so many with worked examples of real-life queries, and none that I can find about how to query by nested attributes.
I'd really appreciate any suggestions. Thanks!
Here's a WAF query that should do the trick for request headers:
WITH waf_data AS (
SELECT
waf.action as action,
waf.httprequest.clientip as clientip,
waf.httprequest.country as country,
map_agg(f.name, f.value) AS kv
FROM "waf_logs" waf,
UNNEST(waf.httprequest.headers) AS t(f)
GROUP BY 1, 2, 3
)
SELECT
waf_data.action,
waf_data.clientip,
waf_data.country,
waf_data.kv['Host'] AS host,
waf_data.kv['User-Agent'] as UserAgent,
waf_data.kv['Cookie'] as cookie
FROM waf_data
WHERE waf_data.kv['Host'] like 'waf_alb.us-east-2.elb.amazonaws.com'
LIMIT 10;
I used the following to extract the HTTP header values (here Host field by name):
SELECT action, header.value as hostname, clientip, timestamp
from (
SELECT
httprequest.clientip as clientip,
action,
timestamp,
httprequest.headers as headers
FROM waf_logs
)
cross join unnest(headers) as c(header)
where lower(header.name) = 'host'
I used this post to extract the array of row which is formatted like array(row("name" varchar,"value" varchar)) in the waf logs database

Unable to refresh dynamic data source in PowerBI service via using anonymous web API access?

This relates to my earlier question - How to iterate/loop through next pages in an API request in PowerQuery/PowerBI? ; which was resolved using below code:
//Declare base variables
let
BaseURL = "https://api.aaaaaa.com",
Entity = "/api/v1/user?&limit=1000",
Token = "zzzzzzzzzzzzzzzzzzzzzzzzzzzz",
Options = [Headers=[APITOKEN=Token]],
URL = BaseURL & Entity,
//Define a function that would take step/page as parameter and return results
GetData=(page as number) =>
let
Source = Json.Document(Web.Contents(URL & "&step=" & Number.ToText(page), Options)),
Data = try Source[results] otherwise null
in
Data,
//Iterate over GetData () to return all the records until last page i.e. until no "result" is retrieved from the API call
GeneratePageList =
List.Generate( ()=>
[Result = try GetData(1) otherwise null, Page=1],
each [Result] <> null,
each [Result = try GetData([Page]+1) otherwise null, Page=[Page]+1],
each [Result]
)
in
GeneratePageList
However, once this code is published to PowerBI service, we cannot schedule refresh for it, since it gives below error as:-
This dataset includes a dynamic data source. Since dynamic data sources aren't refreshed in the Power BI service, this dataset won't be refreshed. Learn more: https://aka.ms/dynamic-data-sources.
• Data source for Query1Discover Data Sources
Tried RelativePath & Query method as suggested here - https://blog.crossjoin.co.uk/2016/08/16/using-the-relativepath-and-query-options-with-web-contents-in-power-query-and-power-bi-m-code/ and here-
https://blog.crossjoin.co.uk/2019/04/25/skip-test-connection-power-bi-refresh-failures/
But, without any luck, see below how am using it:
let
BaseURL = "https://api.crewhu.com",
Entity = "/api/v1/user?&limit=1000&step=",
Token = "60afbdaf5d7d584762771f36",
Options = [Headers=[X_CREWHU_APITOKEN=Token]],
URL = BaseURL & Entity,
//Define a function that would take step/page as parameter and return results
GetData=(page as number) =>
let
Source = Json.Document(Web.Contents(BaseURL & [RelativePath = Entity, Query=[page]], Options)),
The BaseURL is reachable; but redirects to the login page, where our admin credentials (username+password) on the vendor site works well. However, same credentials do not work when using "Basic" connection method during accessing Web Content. Therefore, tried adding #Authorization = Basic in the header along with API key like - [Headers=[Authorization = Basic, X_CREWHU_APITOKEN=Token]]; but this also didn't work.
We've only got an Open API token/key from the vendor; but even that token/key also doesn't work from when providing that in "Web API" section during connecting/accessing Web Content, it gives error as:- "a web api key can only be specified when a web api key name is provided", but the same key/token works well from within PowerQuery (M) code using anonymous web api call method.
Have tried multiple permutation combinations of providing key/token in the username/password fields as suggested in some sites, but still no luck.

Custom authorization for pages in oracle apex

How can I create an authorization schema for pages?
For example: I have
pages like page1, page2, page3 and page4 with
users as user1, user2, user3 and user4.
When I login
user1 should get only page1 and page4
user2 --> page2 and page3
user3 --> page1 and page3
user4 --> page2 and page4
I.e in a priv table the page numbers and the users are stored. The boolean return value function is working for components, but for the page it shows an error.
How can I write an authorization schema for the above roles?
1 - Go to Shared Components
2 - Click on Authorization Schemes
3 - Create a new scheme of the type "PL/SQL function returning boolean"
4 - Your function should return "false" to denied access
In this pl/sql code you have access to :APP_USER variable and :APP_PAGE_ID (page number).
If you have a function that receives the user and the page and return a boolean checking if he has or no access, so just do:
BEGIN
RETURN MYFUNCTION(:APP_USER, :APP_PAGE_ID);
END;
5 - Go to "Edit Application Properties" > "Security" and choose your
authorization scheme.
6 - You don't need to set for every page the authorization scheme, just do the step 5.
I don't know how is your table. But supposing that it's have two columns like
USER PAGE_NUMBER
user1 1
user1 4
user2 2
user2 3
user3 1
user3 3
user4 2
user4 4
So your function look like this:
CREATE OR REPLACE FUNCTION "MYFUNCTION" (p_user IN VARCHAR2, p_page_number IN NUMBER)
RETURN BOOLEAN AS
v_count NUMBER := 0;
BEGIN
SELECT count(*) INTO v_count
FROM mytable
WHERE user = p_user AND page_number = p_page_number;
IF v_count = 0 THEN
RETURN false;
END IF;
RETURN true;
END;
You should consider a custom Authorization Scheme&Authentication Scheme..
1- Create a table for the users to store each user name and password and put a column for 'user_type', in this column you will have the types of users you have for example: 'dev' for developer and 'adm' for admin ans so on ...
2- Create an plsql function that returns a Boolean (true/false) based on
a query that compares the user name and password you get from the user with the ones stored at your users table.
This function will also set 'Session Variables' to pass the user_name and
user_type after a successful login, something like:
apex_util.set_session_state('SESSION_U_TYPE',temp_type);
apex_util.set_session_state('SESSION_USER_NAME',in_username);
3- At the shared components of your application create 'Application Items' by the same exact names you use in your function (here SESSION_U_TYPE, SESSION_USER_NAME)
4- Edit your 'Log-In' page and remove or comment out the default code and use your function and pass the user_name and password via binding variables
5-Now go to shared components again and create a custom Authorization Scheme, give it a name and choose 'SQL exist' as type and write a sql
query to check the user_type of the current user, something like:
SELECT * FROM my_users
WHERE user_name = :SESSION_USER_NAME AND user_type = 'dev';
Repeat this step to create as many 'access levels' as you need
6- Finally, go to each page and under security section choose the
scheme or the user level you want to allow to access this page
-- Notes:
This is fast solution (but working fine) and you can add many improvements to it for example you should create a procedure to handle the log-in and pass the parameters to the authentication function
YOU HAVE TO HASH THE PASSWORD AS YOU SHOULD NEVER STORE PASSWORD IN PLAIN TEXT!
I hope this was useful
The above authorization schema with return boolean function works for components if we save the component id along with the page id and check for components
But for page authorization its not working and showing error.
tested with the above table structure and function
enter image description here

Retrieve data more than the threshold limit

I want to override the QueryThrottle Setting using SPQueryThrottleOption. This is to be done in Client Object Model.
SPQuery q = new SPQuery();
q.QueryThrottleMode = SPQueryThrottleOption.Override;
Can be done in Client Object Model-Sharepoint 2013?
Please try this:
SPWeb web = SPContext.Current.Web;
SPList list = web.Lists["BigList"];
SPQuery query = new SPQuery();
query.QueryThrottleMode = SPQueryThrottleOption.Override;
SPListItemCollection items = list.GetItems(query);
litMessage.Text = String.Format("This list contains {0} items", items.Count);
The important bit is the 4th line down:
query.QueryThrottleMode = SPQueryThrottleOption.Override;
The SPQueryThrottleOption enumeration has three values: Default, Override, and Strict. If you use the default value, the standard list view threshold applies to all users except local server administrators, who are not bound by either threshold. If you set the query throttle mode to Override, users who have the required permissions in the Web application user policy can query at the higher "auditors and administrators" threshold. Local server administrators remain unbound by either threshold. Finally, if you set the query throttle mode to Strict, this closes down the local server administrator loophole and the standard list view threshold applies to all users.