-- @path ASAMM=/InterComponentCommunicationModeling/MetaModels/ASAMM.ecore
-- @path ANOMM=/InterComponentCommunicationModeling/MetaModels/ANO.ecore

module CustomPermissionVulnerabilityIntraApp;
create OUT : ANOMM from IN : ASAMM;

helper context OclAny def:getAllCustomPermissions :Sequence(ASAMM!CustomPermission) =
ASAMM!CustomPermission.allInstances();

helper context OclAny def:getApplicationPolicyFile :ASAMM!ApplicationPolicyFile =
 if self.oclIsTypeOf(ASAMM!ApplicationPolicyFile) then
  self
 else
	self.refImmediateComposite().getApplicationPolicyFile
 endif;

helper context OclAny def:getAppCompPermissionForOneComponent :Sequence(ASAMM!AppCompPermission)=
   if self.getApplicationPolicyFile.appCompPermissions->select(c | self.Name.toString().endsWith(c.AppComponentName.toString())).notEmpty() then
     self.getApplicationPolicyFile.appCompPermissions->select(c | self.Name.toString().endsWith(c.AppComponentName.toString())).flatten()
   else
   	OclUndefined
   endif;

helper context OclAny def:checkAppCompPermission :Boolean=
 if self.getApplicationPolicyFile.appCompPermissions.notEmpty() then
   if self.getApplicationPolicyFile.appCompPermissions->select(c | self.Name.toString().endsWith(c.AppComponentName.toString())).notEmpty() then
	  if thisModule.getAllCustomPermissions->select(c | self.getAppCompPermissionForOneComponent->exists(a | a.Name=c.name)).notEmpty() then
		 if not self.CheckCallerInfo then
	       true
	     else
	  	    false
	     endif 
	else
		false
	endif
  else
	false
  endif
else
false
endif;

helper context OclAny def:existInCustomPermission(permission_name:String) :Boolean=
 if ASAMM!CustomPermission.allInstances()->select(c | c.name=permission_name).notEmpty() then
  true
 else
 	false
  endif;

helper context OclAny def:checkCustomPermissionVulnerabilityForContentProvider :Boolean =
if not self.URIpermissions.notEmpty() then
    if not self.pathPermissions.notEmpty() then
        if not self.permissions.notEmpty() then
	    false
	    else
	  	    if ASAMM!CustomPermission.allInstances()->select(c | self.permissions->exists(a | a.name=c.name)).notEmpty() then
                if not self.CheckCallerInfo then
                 true
                else
                false
			    endif
		    else
		   	false
		    endif
	    endif
	else
		 if self.pathPermissions->select(c | c.permissions->exists(a | thisModule.existInCustomPermission(a.name))).notEmpty() then
		    if not self.CheckCallerInfo then
               true
            else
               false
			endif
		else
			false
		endif
	endif
else---check uripermissions
false
endif
;

helper context OclAny def:checkCustomPermissionVulnerabilityForActivityOrServiceOrReceiver :Boolean =
 if not self.refImmediateComposite().Permission.oclIsUndefined() then
    if thisModule.getAllCustomPermissions->select(c | c.name=self.refImmediateComposite().Permission).notEmpty() then
        if not self.CheckCallerInfo then
	      true
	    else
	  	 false
	    endif
    else
   	    if self.compPermissions.notEmpty() then
	        if thisModule.getAllCustomPermissions->select(c | self.compPermissions->exists(a | a.Name=c.name)).notEmpty() then
		        if not self.CheckCallerInfo then
	             true
	            else
	  	         false
	           endif
		    else
		 	    self.checkAppCompPermission
			endif
        else
	        self.checkAppCompPermission
        endif
	endif
else
    if self.compPermissions.notEmpty() then
	    if thisModule.getAllCustomPermissions->select(c | self.compPermissions->exists(a | a.Name.toString()=c.name.toString())).notEmpty() then
		    if not self.CheckCallerInfo then
	           true
	        else
	  	       false
	        endif
		else
		 	self.checkAppCompPermission
	     endif
    else
	    self.checkAppCompPermission
    endif
endif
;

helper context OclAny def:checkCustomPermissionVulnerabilityForDynamicRegisteredReceiver :Boolean =
 if not self.refImmediateComposite().Permission.oclIsUndefined() then
    if thisModule.getAllCustomPermissions->select(c | c.name=self.refImmediateComposite().Permission).notEmpty() then
        if not self.CheckCallerInfo then
	      true
	    else
	  	 false
	    endif
    else
   	    if self.compPermissions.notEmpty() then
	        if thisModule.getAllCustomPermissions->select(c | self.compPermissions->exists(a | a.Name=c.name)).notEmpty() then
		        if not self.CheckCallerInfo then
	             true
	            else
	  	         false
	           endif
		    else
		 	    self.checkAppCompPermission
			endif
        else
	        self.checkAppCompPermission
        endif
	endif
else
    if self.compPermissions.notEmpty() then
	    if thisModule.getAllCustomPermissions->select(c | self.compPermissions->exists(a | a.Name.toString()=c.name.toString())).notEmpty() then
		    if not self.CheckCallerInfo then
	           true
	        else
	  	       false
	        endif
		else
		 	self.checkAppCompPermission
	     endif
    else
	    self.checkAppCompPermission
    endif
endif
; 

helper context ASAMM!Component def:getCustomPermissionVulnerability :Sequence(String) =
let ComponentsOfApp : Sequence(ASAMM!Component) = self.refImmediateComposite().components in
ComponentsOfApp->iterate(n ; output : Sequence(String) = Sequence{} | 

if self.Exported then
   if self.oclIsTypeOf(ASAMM!ContentProvider) then--content provider
       if self.checkCustomPermissionVulnerabilityForContentProvider then
	          output->including(': This App has Custom Permission vulnerability in a component with this name:' + ' '+ ':'+ ' ' + self.Name) 
	   else
	 	   output->reject(c | c.Name='')
	   endif
   else
   	   if not self.oclIsTypeOf(ASAMM!ContentProvider) then--Activity or Service or Receiver
		     if self.checkCustomPermissionVulnerabilityForActivityOrServiceOrReceiver then
			           output->including(': This App has Custom Permission vulnerability in a component with this name:' + ' '+ ':'+ ' ' + self.Name) 
	         else
	         	output->reject(c | c.Name='')
			 endif
		   else
				output->reject(c | c.Name='')
		   endif
   endif
else
	output->reject(c | c.Name='')
endif
)->asSet()->asSequence();

helper context ASAMM!DynamicRegisteredComponent def:getCustomPermissionVulnerabilityForDynamicRegisteredComponent :Sequence(String) =
let DynamicRegisteredComponentOfApp : Sequence(ASAMM!DynamicRegisteredComponent) = self.refImmediateComposite().dynamicRegisteredComponents in
DynamicRegisteredComponentOfApp->iterate(n ; output : Sequence(String) = Sequence{} | 

if self.Exported then
   if self.checkCustomPermissionVulnerabilityForDynamicRegisteredReceiver then 
      output->including(': This App has Custom Permission vulnerability in a component with this name:' + ' '+ ':'+ ' ' + self.Name) 
   else
   	output->reject(c | c.Name='')
   endif
else
	output->reject(c | c.Name='')
endif


)->asSet()->asSequence();


rule Component2CustomPermission
 {
	from
	   s:ASAMM!Component
	to
	   t:ANOMM!CustomPermission
	   (             
	 description <-
	  if not thisModule.getAllCustomPermissions.notEmpty() then
		 ' '
	  else
	  	   s.getCustomPermissionVulnerability->iterate(up; output: String = '' | output->concat(up)+'\n') 
		--   'n'
	  endif 
	 )
	  do {
	t.trace<-Sequence{s};
         }
  }

rule DynamicComponent2CustomPermission
 {
	from
	   s:ASAMM!DynamicRegisteredComponent
	to
	   t:ANOMM!CustomPermission
	   (             
	 description <-
	  if not thisModule.getAllCustomPermissions.notEmpty() then
		 ' '
	  else
	  	   s.getCustomPermissionVulnerabilityForDynamicRegisteredComponent->iterate(up; output: String = '' | output->concat(up)+'\n')  
	  endif 
	 )
	  do {
	t.trace<-Sequence{s};
         }
  }