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.
- Emissão de Badges: Geração dinâmica de badges com informações personalizadas e QR Code para validação.
- Validação de Badges: Sistema seguro para autenticar a legitimidade dos badges emitidos.
- Integração com Plataformas Sociais: Facilidade para compartilhar conquistas em plataformas como LinkedIn.
- Análise de Dados: Dashboards para monitoramento do engajamento e progresso dos usuários.
- Gamificação: Elementos de gamificação para aumentar o engajamento e a motivação.
- Utiliza Flask para o backend, integrado com Azure Functions. (Não optei pelo Django pois preferi escolher quais funcionalidades meu sistema ia carregar.)
- Armazenamento de dados com Azure CosmosDB (as MongoDB).
- Armazenamento de arquivos com Azure Blob Storage
- Segurança reforçada através do Azure Key Vault.
- Configure o ambiente Azure (Azure Functions, Azure CosmosDB, Azure Blob Storage, Azure App Configuration, Azure Key Vault).
- Clone o repositório e instale as dependências necessárias.
- Configure as variáveis de ambiente conforme a documentação.
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.
-
Windows 10 1709 (build 16299) ou posterior: Caso possua sistema Linux ou MacOS, ainda é possível instalar o BADGE, basta verificar quais passos abaixo se aplicam e adapta-los a sua necessidade.
-
Winget v1.6+: Siga o passo a passo indicado no site da Microsoft
-
PowerShell v7+: Certifique-se de ter o PowerShell v7 ou superior instalado. Para macOS e Linux, siga as instruções de instalação do PowerShell.
-
Conta no Azure: Crie uma conta gratuita no Azure. Todos os recursos do Azure utilizados foram configurados para usar o minimo de custos possível.
-
Azure CLI v2.56+: Todos os serviços do Azure serão instalados via CLI. Siga o passo a passo indicado no site da Microsoft para instalar ou atualizar.
-
Azure Functions Core Tools v3+: Siga o passo a passo indicado no site da Microsoft
-
Azure PowerShell v11.2+: Siga o passo a passo indicado no site da Microsoft
Install-Module -Name Az -AllowClobber -Scope CurrentUser
- git v2.43+: Siga o passo a passo indicado no site do git
-
Logar no Azure via CLI: Todos os serviços do Azure serão instalados via CLI. Siga o passo a passo indicado no site da Microsoft.
-
Caso possua mais de uma subscription, selecione a desejada: Siga o passo a passo indicado no site da Microsoft
-
Configurar git: Siga o passo a passo indicado no site do git
-
Repo do Badges clonado: Siga o passo a passo indicado no site do git para clonar o repositorio https://github.com/arbgjr/BADGE.git.
-
Criar ou escolher um grupo de recursos no Azure para organização dos recursos que seão criados: Siga o passo a passo indicado no site da Microsoft. Guarde o nome da grupo de recursos criado.
Ex.:
$tagValue="Badge"
$randomIdentifier = Get-Random -Maximum 1000000
$resourceGroupName="rg-badges-$randomIdentifier"
$location="eastus2"
az group create --name $resourceGroupName --location "$location"
- Criar uma Storage Account no Azure: Siga o passo a passo indicado no site da Microsoft. Guarde o nome da Storage Account criada.
- Para utilizar a Storage Account mais barata, recomendo que seja utilizado o parametro --sku Standard_LRS
Ex.:
$storageAccountName="blob-badges-$randomIdentifier"
$skuStorage="Standard_LRS"
az storage account create --name $storageAccountName --location "$location" --resource-group $resourceGroupName --sku $skuStorage
- Recuperar a connection string com o Storage Blob.
Ex.:
$blobConnectionString = az storage account show-connection-string --name $storageaccountName --resource-group $resourceGroupName --query "connectionString" -o tsv
- Criar os containers para fonts e badges:
Ex.:
$BadgeContainerName="badges"
$FontsContainerName="fonts"
az storage container create --name $FontsContainerName --account-name $storageAccountName
az storage container create --name $BadgeContainerName --account-name $storageAccountName
- Criar uma Azure Function Python: Siga o passo a passo indicado no site da Microsoft. Guarde o nome da Function criada.
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
- Ativar a Identidade Gerenciada para a Azure Function:
Ex.:
az functionapp identity assign --name $functionAppName --resource-group $resourceGroupName
$AzFuncPrincipalId = $(az functionapp identity show --name $functionAppName --resource-group $resourceGroupName --query "principalId" -o tsv)
- Criar uma instância de um CosmosDB no Azure com compatibilidade do MongoDB.
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
- Criar um banco MongoDB com nome "dbBadges" no CosmosDB.
Ex.:
$databaseName="dbBadges"
az cosmosdb mongodb database create --account-name $nosqlDBName --name $databaseName --resource-group $resourceGroupName
- Recuperar a connection string com o "dbBadges".
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}@"
- Criar um Azure AppConfig:
Ex.:
$azappconfigName="appconfig-badges-$randomIdentifier"
az appconfig create --location "$location" --name $azappconfigName --resource-group $resourceGroupName
- Recuperar a connection string com o Azure AppConfig:
Ex.:
$appconfigConnectionString = az appconfig credential list --name $appconfigName --resource-group $resourceGroupName --query "[0].connectionString" -o tsv
- Definir permissões no Azure App Configuration para a Identidade Gerenciada do Azure Function:
Ex.:
az role assignment create --assignee $AzFuncPrincipalId --role "Contributor" --scope (az appconfig show --name $azAppConfigName --resource-group $resourceGroupName --query "id" -o tsv)
- Criar um Azure Key Vault:
Ex.:
$keyVaultName = "kv-badges-$randomIdentifier"
az keyvault create --name $keyVaultName --resource-group $resourceGroupName --location $location
$AzKVUri = "https://$keyVaultName.vault.azure.net/"
- Definir permissões no Azure Key Vault para a Identidade Gerenciada do Azure Function:
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
- Adicionar a string de conexão do App Config as configurações de connection string da Azure Function:
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
- Fazer upload do template do Badge: O template do Badge não pode ter fundo transparente, utilizo a premissa de fundo branco.
Ex.:
az storage blob upload --container-name $BadgeContainerName --file "CaminhoDoTemplateDoBadge\template_badge.png" --name "template_badge.png" --account-name $storageAccountName
-
Baixar as fontes abaixo, e descompactar os arquivos baixados:
- [[OBRIGATÓRIA]]Not Color Emoji: https://fonts.google.com/noto/specimen/Noto+Color+Emoji
- Outra Fonte do seu gosto, utilizo a Rubik: https://fonts.google.com/specimen/Rubik
-
Fazer upload dos arquivos para o blob storage: Considero que o comando abaixo está sendo executado de dentro da pasta local do repo do BADGE
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
}
- Gerar URL SAS dos arquivos enviados para o Blob Storage:
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")
}
- Atualizar arquivos com configurações padrão: Caso queira
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
}
- Adicionar configurações ao App Config:
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
- Adicionar configurações ao Key Vault:
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
}
- Inserir no nosql os dados que serão inseridos no template: Sugiro você recuperar o conteudo do arquivo Template.json e inserir diretamente no CosmosDB criado. O nome da Collection deve ser: Templates. E ela deve ficar dentro do dbBadges. A opção do script abaixo é passível de erros.
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
Após instalar os pré-requisitos basta seguir os passos abaixo:
-
Abrir PowerShell como Administrador: Clique com o botão direito no menu Iniciar e selecione "Windows PowerShell (Admin)".
-
Baixe o script com o comando:
curl -L -o install.ps1 https://raw.githubusercontent.com/arbgjr/BADGE/main/install.ps1
-
Edite o arquivo install.ps1 onde estiver indicado.
-
Execute o script abaixo é siga as instruções na tela:
.\install.ps1
- Publicar a Function no Azure: Caso o script acima tenha sido executado a functiona já terá sido publicada, caso contrário siga o passo a passo indicado no site da Microsoft
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.
Vide LICENSE.