Commit 438c1179 by Oleksandr Barabash

routine update. teams app added, cipher added, manifest generator updated

parent 81b6291c
......@@ -7,6 +7,7 @@ from http import HTTPStatus
from aiohttp import web
from aiohttp.web import Request, Response, json_response
from aiohttp.web_fileresponse import FileResponse
from botbuilder.core import (
BotFrameworkAdapterSettings,
TurnContext,
......@@ -17,7 +18,7 @@ from marshmallow import EXCLUDE
from bots import TeamsMessagingExtensionsActionPreviewBot
from bots.exceptions import ConversationNotFound, DataParsingError
from config import AppConfig, COSMOS_CLIENT, KEY_VAULT_CLIENT
from config import AppConfig, COSMOS_CLIENT, KEY_VAULT_CLIENT, TeamsAppConfig
from entities.json.notification import Notification
from utils.cosmos_client import ItemNotFound
from utils.json_func import json_loads
......@@ -160,25 +161,21 @@ async def v1_health_check(_request: Request) -> Response:
try:
container = await COSMOS_CLIENT.get_conversations_container()
data = (await KEY_VAULT_CLIENT.get_secret("adminLogin")).value
return Response(body=json.dumps(dict(data=data)),
key = await KEY_VAULT_CLIENT.create_key("pumpalot")
encrypted_data = await KEY_VAULT_CLIENT.encrypt(key, b"hello")
decrypted_data = await KEY_VAULT_CLIENT.decrypt(key, encrypted_data)
return Response(body=json.dumps(dict(data=decrypted_data)),
status=HTTPStatus.OK,
content_type="application/json")
except Exception as e:
Log.e(TAG, f"v1_health_check::error:{e}", sys.exc_info())
raise
if key is None:
return Response(
status=HTTPStatus.INTERNAL_SERVER_ERROR,
body=json.dumps({"error": "Can't connect to KeyVault"}),
content_type="application/json"
)
if container is None:
return Response(
status=HTTPStatus.INTERNAL_SERVER_ERROR,
body=json.dumps({"error": "Can't connect to CosmosDB"}),
content_type="application/json"
)
return Response(status=HTTPStatus.OK, content_type="application/json")
async def get_app_zip(request: Request) -> FileResponse:
""" Get zip file """
Log.i(TAG, "v1_health_check::ok")
return FileResponse(path=TeamsAppConfig.zip_file)
@web.middleware
......@@ -204,6 +201,7 @@ APP.router.add_get("/api/v1/notification/{notification_id}",
v1_get_notification)
APP.router.add_get("/api/v1/initiations/{notification_id}", v1_get_initiations)
APP.router.add_get("/api/v1/health-check", v1_health_check)
APP.router.add_get("/app.zip", get_app_zip)
BOT.add_web_app(APP)
......
......@@ -94,6 +94,7 @@ class TeamsMessagingExtensionsActionPreviewBot(TeamsActivityHandler):
)
except ItemNotFound:
future.set_exception(ConversationNotFound("not found"))
return
except Exception as e:
future.set_exception(e)
return
......
......@@ -11,6 +11,18 @@ PROJECT_ROOT_PATH = os.path.dirname(os.path.abspath("__file__"))
CARDS_PATH = os.path.join(PROJECT_ROOT_PATH, "assets/cards")
class TeamsAppConfig:
""" Teams app config """
teams_app_items = "teams_app_items"
manifest = os.path.join(PROJECT_ROOT_PATH, teams_app_items,
"manifest,json")
image_192x192 = os.path.join(PROJECT_ROOT_PATH, teams_app_items,
"color_192x192.png")
image_32x32 = os.path.join(PROJECT_ROOT_PATH, teams_app_items,
"outline_32x32.png")
zip_file = os.path.join(PROJECT_ROOT_PATH, teams_app_items, "app.zip")
class TaskModuleConfig:
""" Task Module config """
TITLE = os.environ.get("TASK_MODULE_TITLE",
......@@ -30,10 +42,9 @@ class AppConfig:
TENANT_ID = os.environ.get("TENANT_ID",
"5df91ebc-64fa-4aa1-862c-bdc0cba3c656")
APP_ID = os.environ.get("MS_APP_ID",
"34b032df-9532-48f8-a8a1-0e864f9e5562")
APP_PASSWORD = os.environ.get("MS_APP_PASSWORD",
"7Ll8Q~XeV3D8vNmM3Q4BNyxYUcMrM1SQtghOndxT")
WEB_APP_NAME = os.environ.get("WEB_APP_NAME", "")
APP_ID = os.environ.get("MS_APP_ID", "")
APP_PASSWORD = os.environ.get("MS_APP_PASSWORD", "")
class CosmosDBConfig:
......
......@@ -2,7 +2,7 @@
import asyncio
import random
from concurrent.futures.thread import ThreadPoolExecutor
from typing import Awaitable
from typing import Awaitable, Coroutine
# noinspection PyPackageRequirements
from azure.keyvault.keys import KeyClient, KeyVaultKey
......@@ -48,6 +48,10 @@ class AzureKeyVaultClient:
""" Async get key """
return self.execute_blocking(self.key_client.get_key, name)
def create_key(self, name: str) -> Awaitable["KeyVaultKey"]:
""" Async create key """
return self.execute_blocking(self.key_client.create_rsa_key, name)
async def get_random_key_bl(self) -> KeyVaultKey:
""" Blocking get random key """
keys = await self.execute_blocking(
......@@ -73,3 +77,17 @@ class AzureKeyVaultClient:
cipher = CryptographyClient(key, self.credential)
result = cipher.encrypt(EncryptionAlgorithm.rsa_oaep, data)
return result.ciphertext
def decrypt_bl(self, key: KeyVaultKey, data: bytes) -> bytes:
""" Decrypt data """
cipher = CryptographyClient(key, self.credential)
result = cipher.decrypt(EncryptionAlgorithm.rsa_oaep, data)
return result.plaintext
def encrypt(self, key: KeyVaultKey, data: bytes) -> Coroutine[bytes]:
""" Encrypt data """
return self.execute_blocking(self.encrypt_bl, key, data)
def decrypt(self, key: KeyVaultKey, data: bytes) -> Coroutine[bytes]:
""" Encrypt data """
return self.execute_blocking(self.decrypt_bl, key, data)
""" Teams App Generator """
import json
import os
from zipfile import ZipFile, ZIP_DEFLATED
from config import AppConfig, TeamsAppConfig
manifest = {
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.14/MicrosoftTeams.schema.json",
"version": "1.0.0",
"manifestVersion": "1.0.0",
# "id": "THIS IS AN APP SERVICE ID",
"packageName": "net.azurewebsites.bot-name",
# "name": {
# "short": "Cakebot-3",
# "full": "Cakebot-3"
# },
"developer": {
"name": "Medxnote",
"mpnId": "",
"websiteUrl": "https://medxnote.com",
"privacyUrl": "https://medxnote.com/privacy-policy/",
"termsOfUseUrl": "https://medxnote.com/terms-conditions/"
},
"description": {
"short": "Cakebot-3", "full": "Cakebot-3 Bot"
},
# "icons": {
# "outline": "outline.png",
# "color": "color.png"
# },
"accentColor": "#ffffff",
"staticTabs": [
{"entityId": "conversations", "scopes": ["personal"]},
{"entityId": "about", "scopes": ["personal"]}
],
# "bots": [
# {
# "botId": "THIS IS A BOT SERVICE ID",
# "scopes": ["personal", "team", "groupchat"],
# "isNotificationOnly": False,
# "supportsCalling": False,
# "supportsVideo": False,
# "supportsFiles": False
# }
# ],
"validDomains": [],
# "webApplicationInfo": {"id": "THIS IS AN APP SERVICE ID",
# "resource": ""},
"authorization": {"permissions": {"resourceSpecific": []}}
}
class TeamsAppGenerator:
""" Teams App Generator implementation """
@staticmethod
def gen_manifest():
""" Generate manifest """
# ID
manifest.update(dict(id=AppConfig.APP_ID))
# Namings
details = dict(short=AppConfig.WEB_APP_NAME,
full=AppConfig.WEB_APP_NAME)
manifest.update(dict(name=details))
manifest.update(dict(description=details))
# Bot
bot = dict(botId=AppConfig.CLIENT_ID,
scopes=["personal", "team", "groupchat"],
isNotificationOnly=False,
supportsCalling=False,
supportsVideo=False,
supportsFiles=False)
manifest.update(dict(bots=[bot, ]))
# WebAppInfo
web_app_info = dict(id=AppConfig.APP_ID, resource="")
manifest.update(dict(webApplicationInfo=web_app_info))
#
with open(TeamsAppConfig.manifest, "w") as f:
f.write(json.dumps(manifest))
f.flush()
return TeamsAppConfig.manifest
@staticmethod
def get_zip():
""" Generate the app """
TeamsAppGenerator.gen_manifest()
with ZipFile(TeamsAppConfig.zip_file, "w", ZIP_DEFLATED) as zip_file:
for file in [TeamsAppConfig.manifest,
TeamsAppConfig.image_32x32,
TeamsAppConfig.image_192x192]:
file_name = os.path.basename(file)
zip_file.write(file, arcname=file_name)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment