Showing posts with label Session State. Show all posts
Showing posts with label Session State. Show all posts

Wednesday, November 23, 2016

Setting item session state using AJAX in APEX 5

You probably know about the old way how to do this with htmldb_Get JS object:

  var get = new htmldb_Get(null, $v('pFlowId'), null, 0);
  get.add('F_APP_ITEM', vNewItemValue);
  gReturn = get.get();

You can find more about "the old way" here.

But If you've read APEX 5 Release Notes carefully you know that htmldb_Get object is deprecated and it's moved to legacy.js - and you don't what to use legacy JS in your new, modern and shiny APEX 5 applications. You should use apex.server.process or apex.server.plugin for plugins.

So, how can you do it in APEX 5?
It's easy if you want to set current page item values to session state. For this you have a parameter pageItems which can be of type jQuery selector, jQuery or DOM object or array of item names that identifies the page items:

apex.server.process ('MY_PROCESS', 
  {
     pageItems: '#P1_DEPTNO,#P1_EMPNO'
  }, 
  {
    success: function(pData) { ... do something here ... }
  } 
);

But if you want to do some calculations before request or if you want to set application item value to session state you have to dig a bit deeper into the documentation where you can find that with pData parameter of AJAX requests you can set additional parameters that the wwv_flow.show procedure provides.

If you need to set session state of only one item (page or application) you can use parameters p_arg_name and p_arg_value:

apex.server.process ('MY_PROCESS', 
  {
     p_arg_name: 'F_APP_ITEM',
     p_arg_value: vNewAppItemValue
  }, 
  {
    success: function(pData) { ... do something here ... }
  } 
);

If you need to set session state of more than one item (page or application) you have to use parameters p_arg_names and p_arg_values where you have to pass JS array as parameter:

apex.server.process ('MY_PROCESS', 
  {
     p_arg_names: ['F_APP_ITEM','P1_DEPTNO'],
     p_arg_values: [vNewAppItemValue, vNewItemValue]
  }, 
  {
    success: function(pData) { ... do something here ... }
  } 
);

Enjoy!


Tested on APEX 5.0.4.00.12

Sunday, March 9, 2014

View Item Session State from PL/SQL IDE

One and a half year ago I had a post about viewing data from APEX collections from your favorite PL/SQL IDE (PL/SQL Developer, TOAD, SQL Developer...). Similar to that you can view current item session state. First step should be getting grants from some internal APEX packages (executing as sys user):

grant execute on apex_040200.wwv_flow_security to test;
grant execute on apex_040200.wwv_flow_session_state to test;

After that you have to register application and session ID in your PL/SQL IDE (running in parsing schema, e.g. test):

begin
   -- Set Application ID       
   apex_040200.wwv_flow_security.g_flow_id := 121;
      
   -- Set Session ID  
   apex_040200.wwv_flow_security.g_instance := 802090201361;   
end; 

Any time you want to see current session state from some item you have to refresh current session state values by executing:

begin   
   -- Refresh Item Session State Values
   apex_040200.wwv_flow_session_state.fetch_into_substitution_cache(true);
end;

After that you can see value from any item in current session using function v or apex_util.get_session_state, for example:

select v('P1_TEST') from dual

Tested with APEX 4.2.4.00.08 and Oracle XE 11.2.0.2.0 database.

NOTE: It wouldn't be a good idea to give these grants on production instances. :)


Sunday, November 10, 2013

APEX Security Holes - Page Items to Submit Property (Part 1)

I've discovered some interesting things about APEX checksum and item session state. I'll show you some tricks (security holes) and how to avoid them.

Suppose you are authorized to see only departments 10 and 30. Your query should look like this:


  SELECT deptno, dname 
    FROM dept 
   WHERE deptno in (10,30)


and the report page:

where link "View Employees" points to page where you can see all employees in selected department. SQL on that page should look like this:


  SELECT ename    as "Name"
       , job      as "Job"
       , hiredate as "Hire Date"
       , sal      as "Salary"
       , deptno
   FROM emp
  WHERE deptno = :P2_DEPTNO


On this page checksum is turned on so you can't manipulate with URL and change department number:


The link that points to second page should look like this:


  f?p=150:2:6476219590424::NO:2:P2_DEPTNO:30&cs=3DBC2DC62D86556DA878EBB2420F038C0


But if you accidently put item that is used for filtering employees (in my case P2_DEPTNO) to "Page Items To Submit" property of report region there is an easy way to change it and to see employees that you are not supposed to see.


If you clicked on Accounting department on first page you should see 3 employees:





















After that, you just have to open your favorite web debug tool, in my case FireBug, and run following code (where R12587121803287243 is ID of your report region) that sets value of item P2_DEPTNO to 20 and refreshes report region:
















Voilà! Now you should see employees in department 20:
























The refresh of region can be done in other ways. For example, by clicking on pagination.
To see if report region have some items to submit in report properties you can execute this line in FireBug console:


  console.log(apex.widget.report.gPageItemsToSubmit);


When you change session state protection property of item P2_DEPTNO to "Checksum Required - ..." refresh of report will not work but neither the pagination on that report.

So watch out with property "Page Items to Submit"!!

In next post I'll show you how can you easily change item session state on some other ways.

Tested on APEX 4.2.3.00.08.

Wednesday, June 5, 2013

Saving Values of Disabled Items to Session State

As you may know disabled items are not submitted in HTML forms (see w3schools.com). It's same for APEX items, at least for ones disabled with dynamic actions or JavaScript/jQuery.

There's a simple workaround for this. You can create dynamic action on event Before Page Submit that executes JavaScript code that will remove HTML attribute disabled from all items on page:

$(':disabled').removeAttr('disabled');

If you want this to work on all pages, put this dynamic action on global page (page 0).

As I said, this will not work for text field items that have property Disabled set to Yes and Save Session State to No. To save this kind of text field items set property Save Session State to Yes. In this case input item will have HTML attribute readonly, instead of disabled.