Sunday, April 10, 2016

Organization Structure

Introduction
All parts of the WCS business whether its actor or entities, including customers, administrators, stores, catalogs and distributors, must be owned by either an organization or organizational unit.

1) Basic WCS Organization Structure
This is how the basic organization structure looks like after the WCS instance creation, regardless of the business model being used-



Root Organization- It's right there at top with all WCS organizations acting as descendants of the root organization. The site administrators are owned by the root organization.

Default Organization- The default organization is owned by the root organization. And this is where all the B2C and guest users point to.

Note: B2C users under the default organization can be managed by an administrator in WCS Accelerator. Business users outside of the default organization e.g. B2B users can be managed in the Organization Administration Console. 
 
 
2) B2C Organization Structure
The B2C organization structure contains three organizations: root, default, and seller-
 

Seller Organization- A seller organization is created to own all the stores (Retailer) and the Seller administrators who maintain the store. 

B2C Seller Organization ( Intermediate and Optional )- An intermediate B2C organization is created to own a single store (Retailer) and Seller administrators. 
 
 3) B2B Direct Organization Structure

 

Buyer Organization- B2B Buyers are represented by a buyer organization in the B2B organization structure. 
4) Extended Sites Organization Structure
The extended sites organization structure consists of the root organization, default organization, extended sites organization, and extended sites seller organization-



Access Control in WCS- Part2


Implementing access control policies

---------------------------------------------
PFB the details to implement access control in different elements-
1) Controller Commands
A.Using SQL Queries-
insert into acrescgry (ACRESCGRY_ID,RESCLASSNAME) values ((select counter from keys where tablename='acrescgry'),'com.sample.commands.MyOrderCmd');
insert into acresact (ACRESCGRY_ID, ACACTION_ID) values ((select counter from keys where tablename='acrescgry'),(select ACACTION_ID from acaction where action='Execute'));
insert into acresgpres (ACRESGRP_ID, ACRESCGRY_ID) values ((select ACRESGRP_ID from acresgrp where MEMBER_ID in (select orgentity_id from orgentity where orgentityname='Root Organization') and GRPNAME='RegisteredUserCmdResourceGroup'), (select counter from keys where tablename='acrescgry'));
update keys set counter=counter+1 where tablename =’acrescgry’;

B. Using ACPLOAD utlility-
<Policies>
                <Action Name="ExecuteCommand"  CommandName="Execute"/>
                <ResourceCategory Name="com.ibm.commerce.sample.commands.MyControllerCmdResourceCategory"
                                ResourceBeanClass="com.ibm.commerce.sample.commands.MyControllerCmd">
                                <ResourceAction Name="ExecuteCommand"/>
                </ResourceCategory>    
                <ResourceGroup Name="AllSiteUserCmdResourceGroup"  OwnerID="RootOrganization">
                                <ResourceGroupResource Name="com.ibm.commerce.sample.commands.MyControllerCmdResourceCategory"/>
                </ResourceGroup>
</Policies>


2) Views

A.Using SQL Queries-
insert into acaction (acaction_id, action) values ((select counter from keys where tablename='acaction'), 'MyView');
insert into acactactgp (ACACTGRP_ID,ACACTION_ID) values ((SELECT ACACTGRP_ID FROM ACACTGRP WHERE GROUPNAME = 'AllSiteUsersViews' and member_id in (select orgentity_id from orgentity where orgentityname='Root Organization') ), (select acaction_id from acaction where action='MyView'));
update keys set counter=counter+1 where tablename ='acaction';

B. Using ACPLOAD utlility-
<Policies>
                <Action Name="SpecialOrderView" CommandName="SpecialOrderView"/>
                <ActionGroup Name="AllSiteUsersViews" OwnerID="RootOrganization">
                                <ActionGroupAction Name="SpecialOrderView"/>
                </ActionGroup>
</Policies>

3) BOD command framework
Resources that the BOD commands act upon are nouns are represented by generated Java objects. These generated Java objects do not implement the Protectable interface required by the PolicyManager. 
To address this requirement, a wrapper object must be implemented for each noun to extract the information required by the PolicyManager to perform authorization checks. This mapping is defined in the wc-component.xml file

For SOI name-value pair commands, before they run, a command level and a resource level authorization is performed. 

In the BOD command framework, only resource level access control checks are performed, except for Get requests, where Get performs an access control check on whether the request is allowed to use the specified access profile.

There are two assets that need to be implemented for access control for a BOD command:
A. The Protectable Proxy class that represents the noun
B. Access control policies that grant user access to the particular command.
 
4) Enterprise Beans
Access control starts from the step when remote interface of the bean extends the com.ibm.commerce.security.Protectable interface at the time of creation

The enterprise bean class inherits default implementations for the following methods from com.ibm.commerce.base.objects.ECEntityBean:
      
fulfills()- The fulfills method must be implemented if there is an access control policy that includes this resource in its resource group, and also specifies a relationship or relationship group.
default returns false

getGroupingAttributeValue()- The getGroupingAttributeValue method must be implemented if there is an access control policy with an implicit resource group that includes certain instances of this resource, based on specific attribute values (for example, if there were an access control policy that pertains only pertains to Orders with status = 'P' (pending))
default returns null

getOwner()- Note that if the only relationship needed is "owner", then you do not need to override the fulfills method. In this case, the policy manager will make use of the result of the getOwner() method. 
default returns null

5) Data Beans
If a data bean is to be protected, it can either be directly, or indirectly protected by access control policies. 
If a data bean is directly protected, then there exists an access control policy that applies to that particular data bean. 
If a data bean is indirectly protected, it delegates protection to another data bean, for which an access control policy exists.

If you create a new data bean that is to be directly protected by an access control policy, the data bean must do the following:

A. Implement the com.ibm.commerce.security.Protectable interface. As such, the bean must provide an implementation of the getOwner() and fulfills(Long member, String relationship) methods. When a data bean implements the Protectable interface, the data bean manager calls the isAllowed method to determine if the user has the appropriate access control privileges, based upon the existing access control policies. The isAllowed method is described by the following code snippet:
    isAllowed(Context, "Display", protectable_databean);
    where protectable_databean is the data bean to be protected.
               
B. If resources that the bean interacts with are grouped by an attribute other than the resource's Java class name, the bean must implement the com.ibm.commerce.grouping.Groupable interface.
   
C. Implement the com.ibm.commerce.security.Delegator interface. This interface is described by the following code snippet:
    Interface Delegator {
            Protectable getDelegate();
    }
    Note: In order to be directly protected, the getDelegate method should return the data bean itself (that is, the data bean delegates to itself for the purpose of access control).

6) REST Services
A. For Create, Update, and Delete operations:
REST services must wrap BOD commands or controller commands to have access control enforced. This is the only supported and secure option.

B. For Get operations:
REST services must wrap BOD commands or data beans to have access control enforced.
REST over data beans: Access control is enforced if the underlying data bean implements the Delegator interface. If the data bean does not implement the Delegator interface, it can be called using local binding through JSP files, assuming the data bean does not expose sensitive data to the end user. If you are using remote binding through REST service calls, and the data bean does not implement the Delegator interface, only a Site Administrator can run the service call by default. This can be customized by overriding the isSiteResource(DataBean) method of the REST Resource Handler class.

Access Control in WCS - Part1

Introduction
----------------
Access control policies are enforced by the access control policy manager. Generally, when a user attempts to access a protected resource, the access control policy manager first determines what access control policies are applicable for that protected resource, and then, based upon the applicable access control policies, it determines if the user is allowed to access the requested resources.

An access control policy is a 4-tuple policy that is stored in the ACPOLICY table
Each access control policy takes the following form:
AccessControlPolicy [UserGroup, ActionGroup, ResourceGroup, Relationship]

The elements in the 4-tuple access control policy specify that a user belonging to a specific user group is permitted to perform actions in the specified action group on resources belonging to the specified resource group, as long as the user satisfies the conditions specified in the relationship or relationship group, with respect to the resource in question.

User/User Group
----------------------

A user group must be associated with member group type of -2. The value of -2 represents an access group and is defined in the MBRGRPTYPE table.

The membership of a user into a particular user group might be stated explicitly or implicitly. An explicit specification occurs if the MBRGRPMBR table states that the user belongs to a particular member group. 
An implicit specification occurs if the user satisfies a condition (for example, all users that fulfill the role of Product Manager) that is stated in the MBRGRPCOND table

Most conditions to include a user in a user group are based upon the user fulfilling a particular role. For example, there could be an access control policy that allows all users that fulfill the Product Manager role to perform catalog management operations. In this case, any user that assigned the Product Manager role in the MBRROLE table is then implicitly included in the user group.

Action/Action Group
--------------------------

The ActionGroup element comes from the ACACTGRP table. An action group refers to an explicitly specified group of actions. The listing of actions is stored in the ACACTION table and the relationship of each action to its action group (or groups) is stored in the ACACTACTGP table. An example of an action group is the "OrderWriteCommands" action group. This action group includes the following actions that are used to update orders:
  • com.ibm.commerce.order.commands.OrderDeleteCmd
  • com.ibm.commerce.order.commands.OrderCancelCmd
  • com.ibm.commerce.order.commands.OrderProfileUpdateCmd
  • com.ibm.commerce.order.commands.OrderUnlockCmd
  • com.ibm.commerce.order.commands.OrderScheduleCmd
  • com.ibm.commerce.order.commands.ScheduledOrderCancelCmd
  • com.ibm.commerce.order.commands.ScheduledOrderProcessCmd
  • com.ibm.commerce.order.commands.OrderItemAddCmd
  • com.ibm.commerce.order.commands.OrderItemDeleteCmd
  • com.ibm.commerce.order.commands.OrderItemUpdateCmd
  • com.ibm.commerce.order.commands.PayResetPMCmd
Resource/Resource Group
--------------------------------

A resource group is a mechanism to group together particular types of resources. Membership of a resource in a resource group can be specified in one of two ways:
    Using the conditions column in the ACRESGRP table
    Using the ACRESGPRES table

Relationship(Optional)
-------------------------------

The access control policy can optionally include either a Relationship or RelationshipGroup element as its fourth element.
If your access control policy uses a Relationship element, this comes from the ACRELATION table. If it includes a RelationshipGroup element, that comes from the ACRELGRP table. Note that neither need be included, but if you include one, you cannot include the other. A RelationshipGroup specification from the ACRELGRP table takes precedence over the Relationship information from the ACRELATION table.

Types
--------
Command-level (Broad),Also known as role-based.
•Specifies that users assigned to a particular role can execute certain commands.
Applied on controller commands and views
•For example,guest users can execute the commands that are contained in action group X.
 
Resource-level (Very fine)
•Specifies the relationship that a user must have with a resource before a given action can be performed.
Applied on databeans
•For example a user can only display an order they created

Mixed
Command-level Access Control determines whether the user is allowed to execute the particular command within the store you have specified. If a policy allows the user to execute the command, a subsequent Resource-level Access Control Policy could be applied to determine whether the user can access the resource in question.




Thursday, April 7, 2016

Bazaarvoice Feed Customization in WCS FEP 5 & 6

Bazaarvoice ratings and reviews in Feture pack 5 & 6
--------------------------------------------------------------------
Bazaarvoice is a software-as-a-service provider that offers ratings and reviews functionality to their clients. Support for the Bazaarvoice Ratings and Reviews component is included in the Aurora starter store in FEP 5 & 6 for Bazaarvoice clients.

Integration components
----------------------------
1) Storefront support
The Bazaarvoice JavaScript library is used in the Aurora JSP files to include ratings and review content in your store pages

2) Smart SEO feed
Bazaarvoice makes available a SEO representation of the User Generated Content (UGC) because search engines like Google do not index JavaScript rendered content in the form of ZIP file that contains small HTML files with Smart SEO content for ratings and reviews that are associated with an account.

3) Product catalog feed
Bazaarvoice requires clients to upload a product catalog feed that contains information about the catalog of the store. This data is used to represnet ratings and reviews on storefrfront pages

Bazaarvoice integration includes a tool that extracts the catalog for a store into an XML file. The tool packages the XML file into a ZIP archive, and uploads the archive to your Bazaarvoice FTP or SFTP site, We will look into the componenets which can be modified to get tailor made catalog feed matching the client needs.

Steps to generate product feed for bazaarvoice
-----------------------------------------------------------
1) Copy the WC_installdir/components/foundation/samples/RRDataExtract directory to WC_installdir/samples.

2) Navigate to the WC_installdir/samples/RRDataExtract directory. The bazaarvoiceFeedProps.properties file is your property_file and fill the values-

storeId- The ID of the store to extract the product catalog feed from.
wcs.admin.user- WebSphere Commerce site administrator user name.
wcs.admin.password- WebSphere Commerce site administrator password.
bv.user.name(Optional)- Your FTP or SFTP account user name for the Bazaarvoice server (bv_username)
bv.user.password(Optional)- Your FTP or SFTP account password for the Bazaarvoice server (bv_password).Encrypt the password with the wcs_encrypt utility.
seo.base.dir (Optional)- The base path into which the Smart SEO content is extracted
data.feed.base.dir- Full path base directory for product catalog feed
langid- The default language for the store.
currency- The default currency for the store.
wc.url.prefix-  The WebSphere Commerce Server host_name and preview port, typically 8007 for HTTP and 8006 for HTTPS. This parameter is used to extract data from certain web service URLs for the product catalog feed.
staging-    Indicates the environment for which to upload/download content to/from Bazaarvoice.
production-  Indicates the environment for which to upload/download content to/from Bazaarvoice.
sftp-  Indicates the method of upload or download feed to and from Bazaarvoice. If false, the method is set to FTP.Default value is true.
antivirus (Optional): Command to invoke for antivirus scan of SEO directory.

3) Navigate to the WC_installdir/components/foundation/bin directory and Run the script or batch file according to the envinment bazaarvoiceDataFeed.sh to initiate the upload of product catalog feed content to Bazaarvoice.

4) Verify that Bazaarvoice collected and processed the product catalog feed upload.

5) Run the script bazaarvoiceSeoFeed.sh to initiate the download of Smart SEO content from Bazaarvoice and Verify that the Smart SEO content was downloaded.


Components to customize the catalog feed
-----------------------------------------------------
Below componenets from the Bazaarvoice feed structure can be customized/modified to generate the tailor made Product Feed-

1) AbstractDataWriter (Class)
2) OutputDataWriter (Class)
3) CatalogEntryCategoryLevelSkuReaderMediator (Mediator class)
4) wc-query-CatalogEntry-admin-get.tpl tpl file
5) performDataExtract.xml (configuration file)
6) wc-dataextract-catalog-entry.xml.template (configuration file)
7) wc-dataextract-catalog-group.xml.template (configuration file)

Checkout Flow in WCS- Step 3

OrderPrepareCmdImpl
This step helps preparing the order for submission by determining its final prices( if we have to make a real time price call then this is the place), discounts, shipping charges, and taxes with the help of PrepareOrderCmd task command doProcess() method. 

It picks up all the current pending orders of the user in the store if no order reference number is specified. The remerge, merge, check, allocate, backorder and reverse parameters are applicable only if ATP inventory is enabled (STORE Table INVENTORYSYSTEM column value -1).

OrderPrepareCmd calls the following task commands in the sequence-
1.ValidateShippingAdjustmentCmd
2.ValidateShippingMethodCmd
3.PrepareOrderCmd

a. Validates the order is in the correct status which must be any one of the P, I, E, W, or N.
b. If the value of the input request property "commit" is 1(default is 0), a new database transaction is started for every order to be prepared. Otherwise, all orders are prepared in one transaction (the default behavior).

code snippet-
if(ibCommit){
MiscCmd.startNewTransaction(getCommandContext());
lockItemSpecificationsInOrders(abOrder);
}

c. ValidateShippingAdjustmentCmd is invoked to validate that the order hasn't changed since a shipping adjustment was added.
d. Finally PrepareOrderCmd task command is called to do pricing, calculation and inventory actions.

doProcess()
a. Delete generated order items (refer to the PREPAREFLAGS column in the ORDERITEMS table).
b. Check that all order items in the order are buyable (refer to the BUYABLE column in the CATENTRY table).
c. Call DoInventoryActionCmd to check the availability of the products with action CHECK_INVENTORY.
d. Obtain latest unit price for each order item, except those with manually overridden prices or are quotations. (refer to PREPAREFLAGS column of the ORDERITEMS table).
e. Re-calculate the amounts for the order.
f. Lock the order to indicate that it is ready for the OrderProcess command. The lock can be reset either by expiry, by changing the Order (for example, by using the OrderItemUpdate command), or explicitly by using the OrderUnlock command. The expiry period for a lock is stored in the QUOTEGOODFOR column of the STORE table.

Code Snippet-
        if(iATPParameters != null && isLockItemSpecInATP())
            lockItemSpecs(iATPParameters.getAllocate(), iATPParameters.getBackorder(),   iATPParameters.getReverse());

        aOrderProcessingUtility.removeGeneratedOrderItems();
        ensureAllOrderItemsAreBuyable(aOrderProcessingUtility);
        aOrderProcessingUtility.updateOrderItemAddresses();
        aOrderProcessingUtility.updateOrderItemConfigurations(getCommandContext());
        updateOrderItemPrices(aOrderProcessingUtility);

        if(iATPParameters != null)
            iATPParameters.refreshAll();

        calculateOrderForFreeGifts(aOrderProcessingUtility);
        aOrderProcessingUtility.checkOrderInventory();
        InventoryManagementHelper.flush();
        calculateOrder(aOrderProcessingUtility);
        aOrderProcessingUtility.saveOrder(); 


OrderProcessCmdImpl
    processOrders() -> processOrderComments() -> OrderCommentRecordContrlCmd
                        -> processOrderChannelId() -> order.BuschnId
                        -> processPIAdd(ibPerformPIAdd=true) -> PIAddCmd, validatePaymentMethodCmd
                        -> callProcessOrder(isUBFEnabled()) -> BusinessFlowUrlEventCmd -> PreProcessOrderCmdImpl
                                                                                                            -> validateOrderState
                                                            -> validateContract() -> CheckCatalogEntryEntitlementCmd
                                                            -> validateShippingAddress()
                                                            -> allocateInventory() -> DoInventoryActionCmd
                                                            -> checkorder() -> CheckOrderCmd
                                                            -> CheckOrderAcceptanceCmd
                                                            -> updateBillingAddress() -> ValidateOrderAddressCmd
                                                            -> CheckPaymentTCsCmd
                                                            -> ProcessOrderCmdImpl
                                                            -> mergeShopperPayInfo
                                                            -> handleOrderFraud()
                                                            -> checkOrderAndItemTotals()
                                                            -> updateInventory()
                                                            -> getInitialAmount() throws exception if dInitialAmount.compareTo(dOrderTotal)
                                                            -> UpdateSpendingLimitCmd
 


Checkout Flow in WCS- Step 2

Introduction
------------------

Modifying the orderitem qty, selecting the shipping mode, deleting an existing cart-item are few of the instances which lead to invocation of the orderItemUpdateCmdImpl.
 
OrderItemUpdateCmdImpl again extends the OrderItemBaseCmdImpl command which contains the logic for update to the cart , commands called in the sequence-



1)DoInventoryActionCmd(Reserve Inventory)
2)AddOrderItemComponentsCmd
3)ResolveOrderItemPriceCmd
4)UpdateShippingAddressCmd
5)--ValidateTradingPaymentCmd
6)DoInventoryActionCmd(Check Inventory)
7)updateShipInfoCmdImpl
8)RaiseOrderEventCmdImpl
9)OrderCalculateCmd
10)ExtendedOrderItemProcessCmd

For all the updated items:
  • ResolveOrderItemPriceCmd command is called to calculate the best suitable price and to update order total.
  • doPrice parameter can be passed to ResolveOrderItemPriceCmd command to control whether the order items can skip pricing again
  • UpdateShippingAddressCmd command is called to update shipping address
  • Update shipping mode
  • --ValidateTradingPaymentCmd coomand is called to validate the payment method is compatible with the trading agreement
  • If doInventory = Y then DoInventoryActionCmd command is called to update the fulfillment centers and check for available inventory
  • UpdateShipInfoCmd command is called to update the shipping instructions, shipping account number and shipping charge type
  • RaiseOrderEventCmd command is called to raise ORDERITEM_CREATION_EVENT or ORDERITEM_UPDATE_EVENT
  • If the flag calculateOrder is set:
    • Call OrderCalculateCmd to do calculations based on the calUsageIds passed in
  • ExtendOrderItemProcessCmd is called to execute any customization logic added