arbgjr / BADGE

BADGE (Badge Authentication and Dynamic Grading Engine)
GNU General Public License v3.0
1 stars 0 forks source link

BADGE (Badge Authentication and Dynamic Grading Engine)

Ultimo Build

Descrição

BADGE é um sistema inovador destinado a autenticar e classificar conquistas por meio de badges digitais. Este sistema permite que empresas e instituições de ensino emitam badges para reconhecer e validar habilidades, realizações e progressos de indivíduos.

Características

Tecnologia

Como Começar

  1. Configure o ambiente Azure (Azure Functions, Azure CosmosDB, Azure Blob Storage, Azure App Configuration, Azure Key Vault).
  2. Clone o repositório e instale as dependências necessárias.
  3. Configure as variáveis de ambiente conforme a documentação.

Instalação do BADGE

Após ler o passo a passo abaixo você pode executar a configuração/instalação automatizada, que fará a configuração do ambiente local e a criação dos recursos no Azure.

Pré-Requisitos

Install-Module -Name Az -AllowClobber -Scope CurrentUser

Instalação

Ex.:

$tagValue="Badge"
$randomIdentifier = Get-Random -Maximum 1000000
$resourceGroupName="rg-badges-$randomIdentifier"
$location="eastus2"
az group create --name $resourceGroupName --location "$location"

Ex.:

$storageAccountName="blob-badges-$randomIdentifier"
$skuStorage="Standard_LRS"
az storage account create --name $storageAccountName --location "$location" --resource-group $resourceGroupName --sku $skuStorage

Ex.:

$blobConnectionString = az storage account show-connection-string --name $storageaccountName --resource-group $resourceGroupName --query "connectionString" -o tsv

Ex.:

$BadgeContainerName="badges"
$FontsContainerName="fonts"
az storage container create --name $FontsContainerName --account-name $storageAccountName
az storage container create --name $BadgeContainerName --account-name $storageAccountName

Ex.:

$functionAppName="func-badges-$randomIdentifier"
$functionsVersion="4"
$pythonVersion="3.11"
az functionapp create --name $functionAppName --storage-account $storageAccountName --consumption-plan-location "$location" --resource-group $resourceGroupName --os-type Linux --runtime python --runtime-version $pythonVersion --functions-version $functionsVersion

Ex.:

az functionapp identity assign --name $functionAppName --resource-group $resourceGroupName
$AzFuncPrincipalId = $(az functionapp identity show --name $functionAppName --resource-group $resourceGroupName --query "principalId" -o tsv)

Ex.:

$nosqlDBName="nosql-badges-$randomIdentifier"
az cosmosdb create --name $nosqlDBName --resource-group $resourceGroupName --default-consistency-level Session  --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --kind MongoDB

Ex.:

$databaseName="dbBadges"
az cosmosdb mongodb database create --account-name $nosqlDBName --name $databaseName --resource-group $resourceGroupName

Ex.:

$keys = az cosmosdb keys list --name $nosqlDBName --resource-group $resourceGroupName --query "primaryMasterKey" -o tsv
$nosqlConnectionString = "mongodb://$nosqlDBName:`$keys@${nosqlDBName}.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@${nosqlDBName}@"

Ex.:

$azappconfigName="appconfig-badges-$randomIdentifier"
az appconfig create --location "$location" --name $azappconfigName --resource-group $resourceGroupName

Ex.:

$appconfigConnectionString = az appconfig credential list --name $appconfigName --resource-group $resourceGroupName --query "[0].connectionString" -o tsv

Ex.:

az role assignment create --assignee $AzFuncPrincipalId --role "Contributor" --scope (az appconfig show --name $azAppConfigName --resource-group $resourceGroupName --query "id" -o tsv)

Ex.:

$keyVaultName = "kv-badges-$randomIdentifier"
az keyvault create --name $keyVaultName --resource-group $resourceGroupName --location $location
$AzKVUri = "https://$keyVaultName.vault.azure.net/"

Ex.:

az keyvault set-policy --name $keyVaultName --object-id $AzFuncPrincipalId --secret-permissions get list set delete --key-permissions get create delete list update --certificate-permissions get list update create delete

Ex.:

$appSettings = Get-AzWebApp -ResourceGroupName $resourceGroupName -Name $functionAppName
$connectionStringName = "AppConfigConnectionString"
$appSettings.SiteConfig.ConnectionStrings.Add((New-Object Microsoft.Azure.Management.WebSites.Models.ConnectionStringInfo -ArgumentList $connectionStringName, $appconfigConnectionString, "Custom"))
Set-AzWebApp -ResourceGroupName $resourceGroupName -Name $functionAppName -AppSettings $appSettings.SiteConfig.AppSettings

Ex.:

az storage blob upload --container-name $BadgeContainerName --file "CaminhoDoTemplateDoBadge\template_badge.png" --name "template_badge.png" --account-name $storageAccountName

Ex.:

$blobUploadParameters = @(
    @{ContainerName=$BadgeContainerName; LocalFilePath="CaminhoDoTemplateDoBadge\template_badge.png"; BlobName="template_badge.png"},
    @{ContainerName=$BadgeContainerName; LocalFilePath=".\badge_data.schema.json"; BlobName="badge_data.schema.json"},
    @{ContainerName=$FontsContainerName; LocalFilePath="CaminhoDaFonteNotoColorEmoji\NotoColorEmoji-Regular.ttf"; BlobName="NotoColorEmoji-Regular.ttf"},
    @{ContainerName=$FontsContainerName; LocalFilePath="CaminhoDaFonteRubikBold\Rubik-Bold.ttf"; BlobName="Rubik-Bold.ttf"},
    @{ContainerName=$FontsContainerName; LocalFilePath="CaminhoDaFonteRubikRegular\Rubik-Regular.ttf"; BlobName="Rubik-Regular.ttf"}
)

$blobUploadParameters | ForEach-Object {
    az storage blob upload --container-name $_.ContainerName --file $_.LocalFilePath --name $_.BlobName --account-name $storageAccountName
}

Ex.:

$blobFiles = @(
    @{ContainerName=$BadgeContainerName; BlobName='template_badge.png'; BlobUrlVariableName='blobUrlTemplateBadge'},
    @{ContainerName=$BadgeContainerName; BlobName='badge_data.schema.json'; BlobUrlVariableName='BadgeDBSchemaURL'},
    @{ContainerName=$FontsContainerName; BlobName='NotoColorEmoji-Regular.ttf'; BlobUrlVariableName='blobUrlNotoColorEmoji'},
    @{ContainerName=$FontsContainerName; BlobName='Rubik-Bold.ttf'; BlobUrlVariableName='blobUrlRubikBold'},
    @{ContainerName=$FontsContainerName; BlobName='Rubik-Regular.ttf'; BlobUrlVariableName='blobUrlRubikRegular'}
)

$blobFiles | ForEach-Object {
    $expiryDate = (Get-Date -Year (Get-Date).Year -Month 12 -Day 31 -Hour 23 -Minute 59 -Second 59).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
    $sasToken = az storage blob generate-sas --container-name $_.ContainerName --name $_.BlobName --permissions r --expiry $expiryDate --account-name $storageAccountName --https-only --output tsv
    Set-Variable -Name $_.BlobUrlVariableName -Value ("https://$storageAccountName.blob.core.windows.net/$($_.ContainerName)/$($_.BlobName)?$sasToken")
}

Ex.:

$issuerName="Acme Industries"
$areaName="AsPoNe"

$arquivosEValores = @(
    @{Caminho=".\BadgeHeaderInfo.json"; ValorAntigo="<blobUrlRubikRegular>"; ValorNovo=$blobUrlRubikRegular},
    @{Caminho=".\template.json"; ValorAntigo="<issuerName>"; ValorNovo=$issuerName},
    @{Caminho=".\template.json"; ValorAntigo="<areaName>"; ValorNovo=$areaName},
    @{Caminho=".\template.json"; ValorAntigo="<blobUrlRubikBold>"; ValorNovo=$blobUrlRubikBold},
    @{Caminho=".\template.json"; ValorAntigo="<blobUrlNotoColorEmoji>"; ValorNovo=$blobUrlNotoColorEmoji}
)
$arquivosEValores | ForEach-Object {
    $conteudoDoArquivo = Get-Content -Path $_.Caminho -Raw
    $conteudoDoArquivoAtualizado = $conteudoDoArquivo -replace $_.ValorAntigo, $_.ValorNovo
    Set-Content -Path $_.Caminho -Value $conteudoDoArquivoAtualizado
}

Ex.:

$BadgeVerificationUrl="https://www.qualquerurl.com"
$LinkedInPost=""Estou muito feliz em compartilhar que acabei de conquistar um novo badge: {badge_name}!\r\nEsta conquista representa {additional_info}.\r\nVocê pode verificar a autenticidade do meu badge aqui: {validation_url}\r\n#Conquista #Badge #DesenvolvimentoProfissional"

$newSettings = @(
                @{name='AzKVURI'; value=$AzKVURI},
                @{name='BadgeContainerName'; value=$BadgeContainerName},
                @{name='BadgeDBSchemaURL'; value=$BadgeDBSchemaURL},
                @{name='BadgeVerificationUrl'; value=$BadgeVerificationUrl},
                @{name='LinkedInPost'; value=$LinkedInPost}
            )
$newSettings | ForEach-Object {Set-AppConfigKeyValue -azAppConfigName $azappconfigName -settingName $_.name -settingValue $_.value -ContentType "text/plain;charset=utf-8" -tag $tagValue}

$contentBadgeHeaderInfo = Get-Content -Path ".\BadgeHeaderInfo.json" -Raw
az appconfig kv set --name $azappconfigName --key BadgeHeaderInfo --value $content --content-type "application/json" --label $tagValue

Ex.:

$keyVaultSecretParameters = @(
    @{SecretName="BlobConnectionString"; SecretValue=$blobConnectionString; ContentType="text/plain; charset=utf-8"},
    @{SecretName="CosmosDBConnectionString"; SecretValue=$nosqlConnectionString; ContentType="text/plain; charset=utf-8"}
)

$keyVaultSecretParameters | ForEach-Object {
    az keyvault secret set --vault-name $keyVaultName --name $_.SecretName --value $_.SecretValue --content-type $_.ContentType
}

Ex.:

$verb = "POST"
$resourceType = "docs"
$resourceLink = "dbs/$databaseName/colls/Templates"
$resourceKey = $keys # Chave primária do Cosmos DB
$date = [DateTime]::UtcNow.ToString("R")

$keyBytes = [System.Text.Encoding]::UTF8.GetBytes($resourceKey)
$hashAlgorithm = [System.Security.Cryptography.HMACSHA256]::new($keyBytes)
$stringToSign = $verb.ToLower() + "`n" + $resourceType.ToLower() + "`n" + $resourceLink + "`n" + $date.ToLower() + "`n" + "" + "`n"
$signatureBytes = $hashAlgorithm.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signatureBytes)

$authHeader = @{
    Authorization=("type=master&ver=1.0&sig=" + $signature)
    "x-ms-date"=$date
}

$uriCosmosDB = "https://$nosqlDBName.documents.azure.com:443/dbs/$databaseName/colls/Templates/docs"

$arquivoJson = ".\template.json"
$conteudoJson = Get-Content -Path $arquivoJson -Raw

$response = Invoke-RestMethod -Method Post -Uri $uriCosmosDB -Body $conteudoJson -Headers $authHeader -ContentType "application/json"

$response

Automatizando a instalação

Após instalar os pré-requisitos basta seguir os passos abaixo:

  1. Abrir PowerShell como Administrador: Clique com o botão direito no menu Iniciar e selecione "Windows PowerShell (Admin)".

  2. Baixe o script com o comando:

    curl -L -o install.ps1 https://raw.githubusercontent.com/arbgjr/BADGE/main/install.ps1
  3. Edite o arquivo install.ps1 onde estiver indicado.

  4. Execute o script abaixo é siga as instruções na tela:

    .\install.ps1

Contribuições

Contribuições são bem-vindas! Para contribuir, siga as diretrizes de contribuição no repositório. E sempre siga nosso código de conduta.

Licença

Vide LICENSE.