[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
clear
$egurkhaPath=(Get-Item Env:EGURKHA_INSTALL_DIR).value.ToString()
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$egEncryPath=$scriptPath+"\EGFileEncryption.psm1"
$egDatnKy=$scriptPath+"\GetDatnKeyFiles.psm1"
Import-Module $egEncryPath,$egDatnKy -WarningAction SilentlyContinue


Function GetRequiredPermissions($requiredDelegatedPermissions, $requiredApplicationPermissions, $reqsp) {
    $sp = $reqsp
    $appid = $sp.AppId
    $requiredAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
    $requiredAccess.ResourceAppId = $appid
    $requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]
    if ($requiredDelegatedPermissions) {
        AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType "Scope"
    } 
    if ($requiredApplicationPermissions) {
        AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType "Role"
    }
    return $requiredAccess
}

Function AddResourcePermission($requiredAccess, $exposedPermissions, $requiredAccesses, $permissionType) {
    foreach ($permission in $requiredAccesses) {
        $reqPermission = $null
        $reqPermission = $exposedPermissions | Where-Object {$_.Value -contains $permission.Value}
        #Write-Host "Collected information for $($reqPermission.Value) of type $permissionType" -ForegroundColor Green
        $resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
        $resourceAccess.Type = $permissionType
        $resourceAccess.Id = $reqPermission.Id    
        $requiredAccess.ResourceAccess.Add($resourceAccess)
    }
}

######***GUI****#######
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

   $form = New-Object System.Windows.Forms.Form
    $buttonOK = New-Object System.Windows.Forms.Button
    $textbox1=New-Object System.Windows.Forms.TextBox
    $label1=New-Object System.Windows.Forms.Label
    $textbox2=New-Object System.Windows.Forms.TextBox
    $label2=New-Object System.Windows.Forms.Label

    $textbox3=New-Object System.Windows.Forms.TextBox
    $label3=New-Object System.Windows.Forms.Label
    $textbox4=New-Object System.Windows.Forms.TextBox
    $label4=New-Object System.Windows.Forms.Label
    $label5=New-Object System.Windows.Forms.Label

    $O365DtlsLbl=New-Object System.Windows.Forms.Label
    $O365UsrLbl=New-Object System.Windows.Forms.Label
    $O365UsrTxtBx=New-Object System.Windows.Forms.TextBox
    $O365PassLbl=New-Object System.Windows.Forms.Label
    $O365PassTxtBx=New-Object System.Windows.Forms.TextBox
    
    $totalvalues = ($onames.count)
    $formsize = 270 + (30 * $totalvalues)
    $flowlayoutsize = 10 + (30 * $totalvalues)
    $buttonplacement = 210 + (30 * $totalvalues)

    $form.Controls.Add($O365DtlsLbl)
    $form.Controls.Add($O365UsrLbl)
    $form.Controls.Add($O365UsrTxtBx)
    $form.Controls.Add($O365PassLbl)
    $form.Controls.Add($O365PassTxtBx)
    $form.Controls.Add($label5)
    $form.Controls.Add($label1)
    $form.Controls.Add($textbox1)
    $form.Controls.Add($label2)
    $form.Controls.Add($textbox2)
    $form.Controls.Add($label3)
    $form.Controls.Add($textbox3)
    $form.Controls.Add($label4)
    $form.Controls.Add($textbox4)
    $form.Controls.Add($buttonOK)
    $form.AcceptButton = $buttonOK
    $form.AutoScaleDimensions = '8, 17'
    $form.AutoScaleMode = 'Font'
    $form.ClientSize = "380 , $formsize"
    $form.FormBorderStyle = 'FixedDialog'
    $form.Margin = '5, 5, 5, 5'
    $form.MaximizeBox = $False
    $form.MinimizeBox = $False
    $form.Name = 'form1'
    $form.StartPosition = 'CenterScreen'
    $form.Text = 'O365 Graph API'
    $form.add_Load($($form_Load))

    $O365DtlsLbl.Location="38,15"
    $O365DtlsLbl.Anchor="Bottom, Left"
    $O365DtlsLbl.Text="&O365 Details :"
    $O365DtlsLbl.Size="100,20"

    $O365UsrLbl.Location="38,38"
    $O365UsrLbl.Anchor="Bottom, Left"
    $O365UsrLbl.Text="&Username"
    $O365UsrLbl.Size="60,20"

    $O365UsrTxtBx.Location="105,38"
    $O365UsrTxtBx.Name="O365User"
    $O365UsrTxtBx.Size="200,20"
    $O365UsrTxtBx.Text="none"

    $O365PassLbl.Location="38,67"
    $O365PassLbl.Anchor="Bottom, Left"
    $O365PassLbl.Text="&Password"
    $O365PassLbl.Size="60,20"

    $O365PassTxtBx.Location="105,67"
    $O365PassTxtBx.Name="O365Pass"
    $O365PassTxtBx.Size="200,20"
    $O365PassTxtBx.Text="none"
    $O365PassTxtBx.PasswordChar='*'


    $label5.Location="38,95"
    $label5.Anchor="Bottom, Left"
    $label5.Text="&Proxy Details :"
    $label5.Size="100,20"

    $label1.Location="38,118"
    $label1.Anchor="Bottom, Left"
    $label1.Text="&Host IP"
    $label1.Size="60,20"

    $textbox1.Location="105,118"
    $textbox1.Name="ProxyHost"
    $textbox1.Size="120,20"
    $textbox1.Text="none"

    $label2.Location="228,118"
    $label2.Anchor="Bottom, Left"
    $label2.Text="&Port"
    $label2.Size="25,20"

    $textbox2.Location="255,118"
    $textbox2.Name="Port"
    $textbox2.Size="50,20"
    $textbox2.Text="none"

    $label3.Location="38,145"
    $label3.Anchor="Bottom, Left"
    $label3.Text="&Username"
    $label3.Size="60,20"

    $textbox3.Location="105,145"
    $textbox3.Name="ProxyUser"
    $textbox3.Size="200,20"
    $textbox3.Text="none"

    $label4.Location="38,171"
    $label4.Anchor="Bottom, Left"
    $label4.Text="&Password"
    $label4.Size="60,20"

    $textbox4.Location="105,171"
    $textbox4.Name="ProxyPass"
    $textbox4.Size="200,20"
    $textbox4.Text="none"
    $textbox4.PasswordChar='*'

    $buttonOK.Anchor = 'Bottom, Right'
    $buttonOK.DialogResult = 'OK'
    $buttonOK.Location = "150, $buttonplacement"
    $buttonOK.Margin = '4, 4, 4, 4'
    $buttonOK.Name = 'buttonOK'
    $buttonOK.Size = '100, 30'
    $buttonOK.TabIndex = 0
    $buttonOK.Text = '&OK'

    $frmDialog=$form.ShowDialog()
######### END ###########
if($frmDialog -eq 'OK'){
    $userName=$O365UsrTxtBx.Text
    $password=$O365PassTxtBx.Text
    $proxyHost=$textbox1.Text
    $proxyPort=$textbox2.Text
    $proxyUsr=$textbox3.Text
    $proxyPass=$textbox4.Text
    $proxyServer='none'
    if($proxyHost -notcontains 'none' -and $proxyPort -notcontains 'none'){
        $proxyServer='http://'+$proxyHost+':'+$proxyPort
    }
    if($userName -ne 'none' -and $password -ne 'none'){
        Try{
            $initialDomain=Eg-GetDomain -userName $userName -Password $password -proxyUsr $proxyUsr -proxyPass $proxyPass -proxyserver $proxyServer -IsIntial $true -ErrorAction SilentlyContinue
            $initialDomain=$initialDomain.Replace('.onmicrosoft.com','')
            #Write-Host $initialDomain

            $azureVal=Eg-GetAzureEnv -UserName $userName
            $azureEnvArr=$azureVal.Split(',')

            $applicationName='eGMsGraphRpt'
            $KeyDesc='SecreteG'
            $replyUrl='https://'+$initialDomain+'-my.sharepoint.com/'
            $identyUri='https://eGMsGraphRpt.com'

            $srchStrArr=@("Graph#Microsoft Graph","WinAzure#Windows Azure Active Directory","SPO#Office 365 SharePoint Online","O365MAPI#Office 365 Management APIs")
            $reqPermissionArr=@("GraphRead all usage reportsApp","GraphRead all users' full profilesApp","GraphRead all groupsApp","GraphSign in and read user profileDel","WinAzureSign in and read user profileDel","SPORead items in all site collectionsApp","SPORead and write user filesDel","SPORead user filesDel","O365MAPIRead service health information for your organizationApp")

            #$srchStrArr=@("Graph#Microsoft Graph","WinAzure#Windows Azure Active Directory","Exo#Office 365 Exchange Online","SkyOnlin#Skype for Business Online")
            #$reqPermissionArr=@("GraphRead all audit log dataApp","GraphRead all channel messagesApp","GraphRead your organization’s security eventsApp","GraphRead all OneNote notebooksApp","GraphRead all user mailbox settingsApp","GraphRead all usage reportsApp","GraphRead mail in all mailboxesApp","GraphRead contacts in all mailboxesApp","GraphRead all groupsApp","GraphRead directory dataApp","GraphRead all users' full profilesApp","GraphSign in and read user profileDel",
            #"WinAzureSign in and read user profileDel","ExoRead all users' full profilesApp","ExoRead all users' basic profilesApp","ExoRead all user mailbox settingsApp","ExoRead calendars in all mailboxesApp","ExoRead contacts in all mailboxesApp","ExoRead mail in all mailboxesApp","ExoRead user tasks in all mailboxesApp","ExoRead calendars in all mailboxesApp","ExoRead all users' full profilesDel","ExoRead user mailbox settingsDel","SkyOnlinSend/Receive Audio and Video (preview)App","SkyOnlinSend/Receive PSTN (preview)App","SkyOnlinSend/Receive Instant Messages (preview)App","SkyOnlinRead/write Skype user information (preview)Del","SkyOnlinReceive conversation invites (preview)Del","SkyOnlinRead/write Skype user contacts and groupsDel")

            $writDir=$egurkhaPath+'\agent\O365\MsGraph'
            if(!(Test-Path -Path $writDir)){
                $null=New-Item -ItemType directory -Path $writDir
            }
            $startDate = (Get-Date).AddDays(-1)
            $endDate = $startDate.AddMonths(24)
            $spArr=[System.Collections.ArrayList]@()
            $done=$true
            $credential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $password -asplaintext -force)
            Try{
                Connect-AzureAd  -AzureEnvironment $azureEnvArr[0] -Credential $credential
                $existingapp = $null
                $existingapp = get-azureadapplication -Filter "DisplayName eq '$applicationName'"
                if ($existingapp) {
                    Remove-Azureadapplication -ObjectId $existingApp.objectId
                }

                $requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]
                foreach($str in $srchStrArr){
                    $srchStr=$str -split('#')
                    $appArray = [System.Collections.ArrayList]@()
                    $delArray = [System.Collections.ArrayList]@()
                    $svcPrincipal=Get-AzureADServicePrincipal -SearchString $srchStr[1] | Where-Object {$_.DisplayName -eq $srchStr[1]}
                    $spArr.Add($svcPrincipal)
                    for($i=0;$i -lt $reqPermissionArr.Length;$i++ ){
                        if($reqPermissionArr[$i].StartsWith($srchStr[0])){
                            $grStr=$srchStr[0].ToString().Length
                            $tmpnam=$srchStr[0]
                            while($true){
                                if($reqPermissionArr[$i].StartsWith($tmpnam) -and $reqPermissionArr[$i].EndsWith('App')){
                                    $displayNam=$reqPermissionArr[$i].Substring($grStr)
                                    $appIdx=$displayNam.Length-3
                                    $displayNam=$displayNam.Substring(0,$appIdx)
                                    $appArray.Add($displayNam) 
                                    if($i -lt $reqPermissionArr.Length-1){
                                        $i++
                                    }else{break;}
                                }else{
                                    break;
                                }
                            }
                            while($true){
                                if($reqPermissionArr[$i].StartsWith($tmpnam) -and $reqPermissionArr[$i].EndsWith('Del')){     
                                    $displayNam=$reqPermissionArr[$i].Substring($grStr)
                                    $appIdx=$displayNam.Length-3
                                    $displayNam=$displayNam.Substring(0,$appIdx)
                                    $delArray.Add($displayNam)
                                    if($i -lt $reqPermissionArr.Length-1){
                                        $i++
                                    }else{break;}
                                }else{
                                    break;
                                }
                            }
                            $appValue=$svcPrincipal.AppRoles | Where-Object{$_.DisplayName -in $appArray}
                            $delValue=$svcPrincipal.Oauth2Permissions | Where-Object{$_.AdminConsentDisplayName -in $delArray}
                            $azureAppPermissions = GetRequiredPermissions -reqsp $svcPrincipal -requiredApplicationPermissions $appValue -requiredDelegatedPermissions $delValue
                            $requiredResourcesAccess.Add($azureAppPermissions)
                        }
                    }
                }

                #create new Application
                $aadApplication = New-AzureADApplication -DisplayName $applicationName -ReplyUrls $replyUrl -RequiredResourceAccess $requiredResourcesAccess -IdentifierUris $identyUri
                $null=Get-AzureADOAuth2PermissionGrant -All $true

                #set the secret key for application
                $tmpCreVal=New-AzureADApplicationPasswordCredential -ObjectId $aadApplication.ObjectId -StartDate $startDate -EndDate $endDate -CustomKeyIdentifier $KeyDesc

                #Assign application permissions to the application
                $servicePrincipal = New-AzureADServicePrincipal -AppId $aadApplication.AppId       
                #Write-Host "Assigning Permissions" -ForegroundColor Yellow
                foreach ($app in $requiredResourcesAccess){
        
                    $reqAppSP = $spArr | Where-Object {$_.appid -contains $app.ResourceAppId}
                    #Write-Host "Assigning Application permissions for $($reqAppSP.displayName)" -ForegroundColor DarkYellow
        
                    foreach ($resource in $app.ResourceAccess) {
                        if ($resource.Type -match "Role") {
                            New-AzureADServiceAppRoleAssignment -ObjectId $serviceprincipal.ObjectId -PrincipalId $serviceprincipal.ObjectId -ResourceId $reqAppSP.ObjectId -Id $resource.Id
                        }
                    }      
                }
                #grant oauth2permissions
                Get-AzureADOAuth2PermissionGrant -All $true

                $client_id = $aadApplication.AppId
                $client_secret = $tmpCreVal.Value
                $tenantName=(Get-AzureADTenantDetail).VerifiedDomains.Name
                $authority = "https://login.microsoftonline.com/"
                $resource = "https://graph.microsoft.com"
            }
            Catch{
                $done=$false
                write-host 'Exception occurred >> ' $_.Exception.Message
            }

            if($done){
                $keyFileNam='\GraphDetailsKey.dat'
                $keyPath=$writDir+$keyFileNam
                $unProtFile=$writDir+'\GraphDetails.dat'
                if(Test-Path $unProtFile -PathType Leaf){
                    $unProtPath=$writDir+'\GraphDetails.dat'
                    $kvalue=Get-Content -Path $keyPath
                    Unprotect-File $unProtPath -Algorithm AES -KeyAsPlainText $kvalue -DstSuffix '.txt'
                }

                $chkNam=$applicationName+"-"+$tenantName
                $writPath=$writDir+'\GraphDetails.txt'
                if(Test-Path $writPath -PathType Leaf){
                    $dtls=Get-Content -Path $writPath
                    $j=0
                    $wpath1=$writDir+'\GraphDetails1.txt'
                    for($i=0;$i -lt $dtls.Length;$i++){
                        if($dtls[$i] -match $chkNam){
                            $i=$i+8
                        }
                        Add-Content -Path $wpath1 -Value $dtls[$i]
                    }
                    Remove-Item $writPath
                    if(Test-Path $wpath1 -PathType Leaf){
                        Rename-Item $wpath1 'GraphDetails.txt'
                    }
                }

                '['+$applicationName+'-'+$tenantName+']'| Add-Content $writPath -PassThru
                'client_id~'+$client_id| Add-Content $writPath -PassThru
                'client_secret~'+$client_secret| Add-Content $writPath -PassThru
                'TenantName~'+$tenantName| Add-Content $writPath -PassThru
                'Authority~'+$authority| Add-Content $writPath -PassThru
                'Resource~'+$resource| Add-Content $writPath -PassThru
                "`n"| Add-Content $writPath

                $key=Get-CryptoKey -FileDir $writDir -FileName $keyFileNam
                $null=Protect-File $writPath -Algorithm AES -KeyAsPlainText $key -RemoveSource

                Write-Host 'Permissions provided successfully'
            }



        }Catch{
            #Write-Host $_.Exception.Message
            [system.windows.forms.messagebox]::show("You have entered wrong credentials","O365 Graph API",'Ok')
        }
    }
    else{
        [system.windows.forms.messagebox]::show("You have entered wrong credentials","O365 Graph API",'Ok')
    }
}
#else{
#    [system.windows.forms.messagebox]::show("You have cancelled the credential","O365 Graph API",'Ok')
#}