.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0

Client Configuration
====================

TEST version of "cadi.properties"
---------------------------------
These properties point you to the ONAP TEST environment.  

Properties are separated into

 * etc
    * main Property file which provides Client specific info.  As a client, this could be put in container, or placed on Host Box
    * The important thing is to LINK the property with Location and Certificate Properties, see "local"
 * local
   * where there is Machine specific information (i.e. GEO Location (Latitude/Longitude)
   * where this is Machine specific Certificates (for running services)
       * This is because the certificates used must match the Endpoint that the Container is running on
       * Note Certificate Manager can Place all these components together in one place.
           * For April, 2018, please write Jonathan.gathman@att.com for credentials until TEST Env with Certificate Manager is fully tested.  Include
           1. AAF Namespace (you MUST be the owner for the request to be accepted)
           2. Fully Qualified App ID (ID + Namespace)
           3. Machine to be deployed on.
		   
Client Credentials
------------------
For Beijing, full TLS is expected among all components.  AAF provides the "Certificate Manager" which can "Place" Certificate information 

Example Source Code
-------------------
Note the FULL class is available in the authz repo, cadi_aaf/org/onap/aaf/client/sample/Sample.java

.. code-block:: java


  /**
   * ============LICENSE_START====================================================
   * org.onap.aaf
   * ===========================================================================
   * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
   * ===========================================================================
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   * ============LICENSE_END====================================================
   *
   */
 
  package org.onap.aaf.client.sample;
 
  import java.io.IOException;
  import java.security.Principal;
  import java.util.ArrayList;
  import java.util.List;
 
  import org.onap.aaf.cadi.Access;
  import org.onap.aaf.cadi.CadiException;
  import org.onap.aaf.cadi.LocatorException;
  import org.onap.aaf.cadi.Permission;
  import org.onap.aaf.cadi.PropAccess;
  import org.onap.aaf.cadi.aaf.AAFPermission;
  import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;
  import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;
  import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;
  import org.onap.aaf.cadi.principal.UnAuthPrincipal;
  import org.onap.aaf.cadi.util.Split;
  import org.onap.aaf.misc.env.APIException;
 
  public class Sample {
    private static Sample singleton;
    final private AAFConHttp aafcon;
    final private AAFLurPerm aafLur;
    final private AAFAuthn<?> aafAuthn;
     
    /**
     * This method is to emphasize the importance of not creating the AAFObjects over and over again.
     * @return
     */
    public static Sample singleton() {
        return singleton;
    }
 
    public Sample(Access myAccess) throws APIException, CadiException, LocatorException {
        aafcon = new AAFConHttp(myAccess);
        aafLur = aafcon.newLur();
        aafAuthn = aafcon.newAuthn(aafLur);
    }
     
    /**
     * Checking credentials outside of HTTP/S presents fewer options initially. There is not, for instance,
     * the option of using 2-way TLS HTTP/S.
     * 
     *  However, Password Checks are still useful, and, if the Client Certificate could be obtained in other ways, the
     *  Interface can be expanded in the future to include Certificates.
     * @throws CadiException
     * @throws IOException
     */
    public Principal checkUserPass(String fqi, String pass) throws IOException, CadiException {
        String ok = aafAuthn.validate(fqi, pass);
        if(ok==null) {
            System.out.println("Success!");
            /*
             UnAuthPrincipal means that it is not coming from the official Authorization chain.
             This is useful for Security Plugins which don't use Principal as the tie between
             Authentication and Authorization
             
             You can also use this if you want to check Authorization without actually Authenticating, as may
             be the case with certain Onboarding Tooling.
            */
            return new UnAuthPrincipal(fqi);
        } else {
            System.out.printf("Failure: %s\n",ok);
            return null;
        }
         
 
    }
 
    /**
     * An example of looking for One Permission within all the permissions user has.  CADI does cache these,
     * so the call is not expensive.
     *
     * Note: If you are using "J2EE" (Servlets), CADI ties this function to the method:
     *    HttpServletRequest.isUserInRole(String user)
     *   
     *  The J2EE user can expect that his servlet will NOT be called without a Validated Principal, and that
     *  "isUserInRole()" will validate if the user has the Permission designated.
     * 
     */
    public boolean oneAuthorization(Principal fqi, Permission p) {
        return aafLur.fish(fqi, p);
    }
     
    public List<Permission> allAuthorization(Principal fqi) {
        List<Permission> pond = new ArrayList<Permission>();
        aafLur.fishAll(fqi, pond);
        return pond;
    }
     
     
    public static void main(String[] args) {
        // Note: you can pick up Properties from Command line as well as VM Properties
        // Code "user_fqi=... user_pass=..." (where user_pass can be encrypted) in the command line for this sample.
        // Also code "perm=<perm type>|<instance>|<action>" to test a specific Permission
        PropAccess myAccess = new PropAccess(args);
        try {
            /*
             * NOTE:  Do NOT CREATE new aafcon, aafLur and aafAuthn each transaction.  They are built to be
             * reused!
             *
             * This is why this code demonstrates "Sample" as a singleton.
             */
            singleton = new Sample(myAccess);
            String user = myAccess.getProperty("user_fqi");
            String pass= myAccess.getProperty("user_pass");
             
            if(user==null || pass==null) {
                System.err.println("This Sample class requires properties user_fqi and user_pass");
            } else {
                pass =  myAccess.decrypt(pass, false); // Note, with "false", decryption will only happen if starts with "enc:"
                // See the CODE for Java Methods used
                Principal fqi = Sample.singleton().checkUserPass(user,pass);
                 
                if(fqi==null) {
                    System.out.println("OK, normally, you would cease processing for an "
                            + "unauthenticated user, but for the purpose of Sample, we'll keep going.\n");
                    fqi=new UnAuthPrincipal(user);
                }
                 
                // AGAIN, NOTE: If your client fails Authentication, the right behavior 99.9%
                // of the time is to drop the transaction.  We continue for sample only.
                 
                // note, default String for perm
                String permS = myAccess.getProperty("perm","org.osaaf.aaf.access|*|read");
                String[] permA = Split.splitTrim('|', permS);
                if(permA.length>2) {
                    final Permission perm = new AAFPermission(permA[0],permA[1],permA[2]);
                    // See the CODE for Java Methods used
                    if(singleton().oneAuthorization(fqi, perm)) {
                        System.out.printf("Success: %s has %s\n",fqi.getName(),permS);
                    } else {
                        System.out.printf("%s does NOT have %s\n",fqi.getName(),permS);
                    }
                }
                 
                 
                // Another form, you can get ALL permissions in a list
                // See the CODE for Java Methods used
                List<Permission> permL = singleton().allAuthorization(fqi);
                if(permL.size()==0) {
                    System.out.printf("User %s has no Permissions THAT THE CALLER CAN SEE",fqi.getName());
                } else {
                    System.out.print("Success:\n");
                    for(Permission p : permL) {
                        System.out.printf("\t%s has %s\n",fqi.getName(),p.getKey());
                    }
                }
            }
        } catch (APIException | CadiException | LocatorException | IOException e) {
            e.printStackTrace();
        }
    }
  }