###
# Licensed Materials - Property of IBM* and/or HCL**
# (c) Copyright IBM Corporation 2014, 2015, 2017. All Rights Reserved.
# (c) Copyright HCL Technologies Ltd. 2018. All Rights Reserved.
#
# U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
# GSA ADP Schedule Contract with IBM Corp.
#
# * Trademark of International Business Machines
# ** Trademark of HCL Technologies Limited

from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from utilities import Util
from Property import Property
from TrustAssociation import TrustAssociation
from SingleSignon import SingleSignon
from DigestAuthentication import DigestAuthentication
from SWAMAuthentication import SWAMAuthentication
from LTPA import LTPA
from CustomAuthMechanism import CustomAuthMechanism
from KRB5 import KRB5
from RSAToken import RSAToken
from SPNEGO import SPNEGO

__name_att__ = None;

def _export(objid, parentrespath, name = ""):
  Util.pushPathElement('AuthMechanism')


  if parentrespath == "/":
    parentrespath = "";
  respath = "%(parentrespath)s/%(name)s" % { 'parentrespath':parentrespath, 'name':name }
  if not respath.startswith("/"):
    respath = "/" + respath;

  exportedObject = JSONObject();
  exportedObject.put("name", name);
  exportedObject.put("path", respath);
  exportedObject.put("teamMappings", JSONArray());
  exportedObject.put("inheritTeam", "true");
  exportedObject.put("description", "Discovered WebSphereAuthMechanism");
  exportedObject.put("roleName", "WebSphereAuthMechanism");

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.authmechanism.simpleauthconfig", objid, "simpleAuthConfig","AuthMechanism");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.authmechanism.authcontextimplclass", objid, "authContextImplClass","AuthMechanism");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.authmechanism.authconfig", objid, "authConfig","AuthMechanism");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.authmechanism.iscredentialforwardable", objid, "isCredentialForwardable","AuthMechanism");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.authmechanism.oid", objid, "OID","AuthMechanism");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.authmechanism.authvalidationconfig", objid, "authValidationConfig","AuthMechanism");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};
  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"AuthMechanism");
  trust = Util.getOptionalAttribute(objid, 'trustAssociation', 'AuthMechanism');
  if trust is not None and len(trust) > 0:
    returndict = Util.createTypeFolder(respath, 'TrustAssociation', typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, TrustAssociation._export(trust, currespath, "TrustAssociation"));

  sso = Util.getOptionalAttribute(objid, 'singleSignon', 'AuthMechanism');
  if sso is not None and len(sso) > 0:
    returndict = Util.createTypeFolder(respath, 'SingleSignon', typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, SingleSignon._export(sso, currespath, "SingleSignon"));

  digestAuth = Util.getOptionalAttribute(objid, 'digestAuthentication', 'AuthMechanism');
  if digestAuth is not None and len(digestAuth) > 0:
    returndict = Util.createTypeFolder(respath, 'DigestAuthentication', typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, DigestAuthentication._export(digestAuth, currespath, "DigestAuthentication"));

  if len(extraObjects) != 0:
    result['extraObjects'] = extraObjects;
  Util.popPathElement('AuthMechanism');
  return result;



def create(parentid, jsonobject):
  Util.pushPathElement('AuthMechanism')
  if not jsonobject.has("roleProperties"):
    raise Exception("AuthMechanism resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");

  properties = [];
  Util.addIfNotNone(properties, "simpleAuthConfig", roleProperties.optString("websphere.authmechanism.simpleauthconfig", None));
  Util.addIfNotNone(properties, "authContextImplClass", roleProperties.optString("websphere.authmechanism.authcontextimplclass", None));
  Util.addIfNotNone(properties, "authConfig", roleProperties.optString("websphere.authmechanism.authconfig", None));
  Util.addIfNotNone(properties, "isCredentialForwardable", roleProperties.optString("websphere.authmechanism.iscredentialforwardable", None));
  Util.addIfNotNone(properties, "OID", roleProperties.optString("websphere.authmechanism.oid", None));
  Util.addIfNotNone(properties, "authValidationConfig", roleProperties.optString("websphere.authmechanism.authvalidationconfig", None));
  print "Creating AuthMechanism with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };
  objid = Util.create("AuthMechanism", parentid, properties);
  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      if currole == "WebSphereTrustAssociation":
        TrustAssociation.create(objid, curjsonobject);
      elif currole == "WebSphereSingleSignon":
        SingleSignon.create(objid, curjsonobject);
      elif currole == "WebSphereDigestAuthentication":
        DigestAuthentication.create(objid, curjsonobject);
      else:
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('AuthMechanism');


def update(objid,jsonobject):
  Util.pushPathElement('AuthMechanism')
  if not jsonobject.has("roleProperties"):
    raise Exception("AuthMechanism resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.authmechanism.simpleauthconfig", None), "simpleAuthConfig","AuthMechanism");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.authmechanism.authcontextimplclass", None), "authContextImplClass","AuthMechanism");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.authmechanism.authconfig", None), "authConfig","AuthMechanism");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.authmechanism.iscredentialforwardable", None), "isCredentialForwardable","AuthMechanism");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.authmechanism.oid", None), "OID","AuthMechanism");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.authmechanism.authvalidationconfig", None), "authValidationConfig","AuthMechanism");
  if len(atts) != 0:
    print "Modifying AuthMechanism with attributes:"
    for prop in atts:
      print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

    Util.modify(objid, atts);
  else:   
    print "AuthMechanism configuration up to date.";

  Property.removeProperties(objid, 'properties',"AuthMechanism");

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      if currole == "WebSphereTrustAssociation":
        TrustAssociation.update(objid, curjsonobject);
      elif currole == "WebSphereSingleSignon":
        SingleSignon.update(objid, curjsonobject);
      elif currole == "WebSphereDigestAuthentication":
        DigestAuthentication.update(objid, curjsonobject);
      else:
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('AuthMechanism');

def removeAuthMechanisms(objid, attributeName, parentType):
  auths = Util.parseConfigIdListAttribute(objid, attributeName, parentType);
  if auths is not None and len(auths) > 0:
    for authid in auths:
      if len(authid) > 0:
        Util.remove(authid);

def exportAuthMechanisms(objid, respath, extraObjects, typeFolders, attributeName, parentType, folderName = None):
  counterSWAMAuthentication = 0;
  counterLTPA = 0;
  counterCustomAuthMechanism = 0;
  counterKRB5 = 0;
  counterRSAToken = 0;
  counterSPNEGO = 0;

  auths = Util.parseConfigIdListAttribute(objid, attributeName, parentType);
  if auths is not None and len(auths) > 0:
    for authid in auths:
      if len(authid) > 0:
        if authid.find("#SWAMAuthentication_") != -1:
          if folderName is not None and len(folderName) > 0:
            returndict = Util.createTypeFolder(respath, folderName, typeFolders);
          else:
            returndict = Util.createTypeFolder(respath, "SWAMAuthentication", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          Util.addAllFromExport(extraObjects, SWAMAuthentication._export(authid, currespath, 'SWAMAuthentication%s' % counterSWAMAuthentication));
          counterSWAMAuthentication = counterSWAMAuthentication + 1;
        elif authid.find("#LTPA_") != -1:
          if folderName is not None and len(folderName) > 0:
            returndict = Util.createTypeFolder(respath, folderName, typeFolders);
          else:
            returndict = Util.createTypeFolder(respath, "LTPA", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          Util.addAllFromExport(extraObjects, LTPA._export(authid, currespath, 'LTPA%s' % counterLTPA));
          counterLTPA = counterLTPA + 1;
        elif authid.find("#CustomAuthMechanism_") != -1:
          if folderName is not None and len(folderName) > 0:
            returndict = Util.createTypeFolder(respath, folderName, typeFolders);
          else:
            returndict = Util.createTypeFolder(respath, "CustomAuthMechanism", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          Util.addAllFromExport(extraObjects, CustomAuthMechanism._export(authid, currespath, 'CustomAuthMechanism%s' % counterCustomAuthMechanism));
          counterCustomAuthMechanism = counterCustomAuthMechanism + 1;
        elif authid.find("#KRB5_") != -1:
          if folderName is not None and len(folderName) > 0:
            returndict = Util.createTypeFolder(respath, folderName, typeFolders);
          else:
            returndict = Util.createTypeFolder(respath, "KRB5", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          Util.addAllFromExport(extraObjects, KRB5._export(authid, currespath, 'KRB5%s' % counterKRB5));
          counterKRB5 = counterKRB5 + 1;
        elif authid.find("#RSAToken_") != -1:
          if folderName is not None and len(folderName) > 0:
            returndict = Util.createTypeFolder(respath, folderName, typeFolders);
          else:
            returndict = Util.createTypeFolder(respath, "RSAToken", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          Util.addAllFromExport(extraObjects, RSAToken._export(authid, currespath, 'RSAToken%s' % counterRSAToken));
          counterRSAToken = counterRSAToken + 1;
        elif authid.find("#SPNEGO_") != -1:
          if folderName is not None and len(folderName) > 0:
            returndict = Util.createTypeFolder(respath, folderName, typeFolders);
          else:
            returndict = Util.createTypeFolder(respath, "SPNEGO", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          Util.addAllFromExport(extraObjects, SPNEGO._export(authid, currespath, 'SPNEGO%s' % counterSPNEGO));
          counterSPNEGO = counterSPNEGO + 1;

  return extraObjects;

def createObjIfRole(objid, curjsonobject, currole):
  if currole == "WebSphereSWAMAuthentication":
    SWAMAuthentication.create(objid, curjsonobject);
    return 1;
  elif currole == "WebSphereLTPA":
    LTPA.create(objid, curjsonobject);
    return 1;
  elif currole == "WebSphereCustomAuthMechanism":
    CustomAuthMechanism.create(objid, curjsonobject);
    return 1;
  elif currole == "WebSphereKRB5":
    KRB5.create(objid, curjsonobject);
    return 1;
  elif currole == "WebSphereRSAToken":
    RSAToken.create(objid, curjsonobject);
    return 1;
  elif currole == "WebSphereSPNEGO":
    SPNEGO.create(objid, curjsonobject);
    return 1;
  return 0;

def updateObjIfRole(objid, curjsonobject, currole, parentType):
  if currole != "WebSphereSWAMAuthentication" and \
        currole != "WebSphereLTPA" and \
        currole != "WebSphereCustomAuthMechanism" and \
        currole != "WebSphereKRB5" and \
        currole != "WebSphereRSAToken" and \
        currole != "WebSphereSPNEGO":
    return 0;

  auths = Util.parseConfigIdListAttribute(objid, "authMechanisms", parentType);
  if auths is not None and len(auths) > 0:
    if currole == "WebSphereSWAMAuthentication":
      for authid in auths:
        if authid.find("#SWAMAuthentication_") != -1:
          SWAMAuthentication.update(authid, curjsonobject);
          return 1;
    elif currole == "WebSphereLTPA":
      for authid in auths:
        if authid.find("#LTPA_") != -1:
          LTPA.update(authid, curjsonobject);
          return 1;
    elif currole == "WebSphereCustomAuthMechanism":
      for authid in auths:
        if authid.find("#CustomAuthMechanism_") != -1:
          CustomAuthMechanism.update(authid, curjsonobject);
          return 1;
    elif currole == "WebSphereKRB5":
      for authid in auths:
        if authid.find("#KRB5_") != -1:
          KRB5.update(authid, curjsonobject);
          return 1;
    elif currole == "WebSphereRSAToken":
      for authid in auths:
        if authid.find("#RSAToken_") != -1:
          RSAToken.update(authid, curjsonobject);
          return 1;
    elif currole == "WebSphereSPNEGO":
      for authid in auths:
        if authid.find("#SPNEGO_") != -1:
          SPNEGO.update(authid, curjsonobject);
          return 1;
  return 0;

