Update OSIRIS engine with signatory access control and Freezone examples
This commit is contained in:
@@ -100,6 +100,10 @@ def_package! {
|
||||
.set_into_module(module, |ctx: &mut OsirisContext, flow_instance: crate::objects::FlowInstance| ctx.save_object(flow_instance));
|
||||
FuncRegistration::new("save")
|
||||
.set_into_module(module, |ctx: &mut OsirisContext, verification: crate::objects::Verification| ctx.save_object(verification));
|
||||
FuncRegistration::new("save")
|
||||
.set_into_module(module, |ctx: &mut OsirisContext, email_client: crate::objects::communication::email::EmailClient| ctx.save_object(email_client));
|
||||
FuncRegistration::new("save")
|
||||
.set_into_module(module, |ctx: &mut OsirisContext, mail_template: crate::objects::communication::email::MailTemplate| ctx.save_object(mail_template));
|
||||
FuncRegistration::new("save")
|
||||
.set_into_module(module, |ctx: &mut OsirisContext, account: crate::objects::Account| ctx.save_object(account));
|
||||
FuncRegistration::new("save")
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use super::verification::Verification;
|
||||
use crate::store::{BaseData, Object, Storable};
|
||||
use lettre::{
|
||||
Message, SmtpTransport, Transport,
|
||||
message::{header::ContentType, MultiPart, SinglePart},
|
||||
@@ -11,8 +12,11 @@ use lettre::{
|
||||
};
|
||||
|
||||
/// Email client with SMTP configuration
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, crate::DeriveObject)]
|
||||
pub struct EmailClient {
|
||||
#[serde(flatten)]
|
||||
pub base_data: BaseData,
|
||||
|
||||
/// SMTP server hostname
|
||||
pub smtp_host: String,
|
||||
|
||||
@@ -35,9 +39,64 @@ pub struct EmailClient {
|
||||
pub use_tls: bool,
|
||||
}
|
||||
|
||||
/// Mail template with placeholders
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, crate::DeriveObject)]
|
||||
pub struct MailTemplate {
|
||||
#[serde(flatten)]
|
||||
pub base_data: BaseData,
|
||||
|
||||
/// Template ID
|
||||
pub id: String,
|
||||
|
||||
/// Template name
|
||||
pub name: String,
|
||||
|
||||
/// Email subject (can contain placeholders like ${name})
|
||||
pub subject: String,
|
||||
|
||||
/// Email body (can contain placeholders like ${code}, ${url})
|
||||
pub body: String,
|
||||
|
||||
/// HTML body (optional, can contain placeholders)
|
||||
pub html_body: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for MailTemplate {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseData::new(),
|
||||
id: String::new(),
|
||||
name: String::new(),
|
||||
subject: String::new(),
|
||||
body: String::new(),
|
||||
html_body: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Email message created from a template
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct Mail {
|
||||
/// Recipient email address
|
||||
pub to: String,
|
||||
|
||||
/// Template ID to use
|
||||
pub template_id: Option<String>,
|
||||
|
||||
/// Parameters to replace in template
|
||||
pub parameters: std::collections::HashMap<String, String>,
|
||||
|
||||
/// Direct subject (if not using template)
|
||||
pub subject: Option<String>,
|
||||
|
||||
/// Direct body (if not using template)
|
||||
pub body: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for EmailClient {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseData::new(),
|
||||
smtp_host: "localhost".to_string(),
|
||||
smtp_port: 587,
|
||||
username: String::new(),
|
||||
@@ -49,6 +108,105 @@ impl Default for EmailClient {
|
||||
}
|
||||
}
|
||||
|
||||
impl MailTemplate {
|
||||
/// Create a new mail template
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Builder: Set template ID
|
||||
pub fn id(mut self, id: String) -> Self {
|
||||
self.id = id;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set template name
|
||||
pub fn name(mut self, name: String) -> Self {
|
||||
self.name = name;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set subject
|
||||
pub fn subject(mut self, subject: String) -> Self {
|
||||
self.subject = subject;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set body
|
||||
pub fn body(mut self, body: String) -> Self {
|
||||
self.body = body;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set HTML body
|
||||
pub fn html_body(mut self, html_body: String) -> Self {
|
||||
self.html_body = Some(html_body);
|
||||
self
|
||||
}
|
||||
|
||||
/// Replace placeholders in text
|
||||
fn replace_placeholders(&self, text: &str, parameters: &std::collections::HashMap<String, String>) -> String {
|
||||
let mut result = text.to_string();
|
||||
for (key, value) in parameters {
|
||||
let placeholder = format!("${{{}}}", key);
|
||||
result = result.replace(&placeholder, value);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Render subject with parameters
|
||||
pub fn render_subject(&self, parameters: &std::collections::HashMap<String, String>) -> String {
|
||||
self.replace_placeholders(&self.subject, parameters)
|
||||
}
|
||||
|
||||
/// Render body with parameters
|
||||
pub fn render_body(&self, parameters: &std::collections::HashMap<String, String>) -> String {
|
||||
self.replace_placeholders(&self.body, parameters)
|
||||
}
|
||||
|
||||
/// Render HTML body with parameters
|
||||
pub fn render_html_body(&self, parameters: &std::collections::HashMap<String, String>) -> Option<String> {
|
||||
self.html_body.as_ref().map(|html| self.replace_placeholders(html, parameters))
|
||||
}
|
||||
}
|
||||
|
||||
impl Mail {
|
||||
/// Create a new mail
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Builder: Set recipient
|
||||
pub fn to(mut self, to: String) -> Self {
|
||||
self.to = to;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set template ID
|
||||
pub fn template(mut self, template_id: String) -> Self {
|
||||
self.template_id = Some(template_id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Add a parameter
|
||||
pub fn parameter(mut self, key: String, value: String) -> Self {
|
||||
self.parameters.insert(key, value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set subject (for non-template emails)
|
||||
pub fn subject(mut self, subject: String) -> Self {
|
||||
self.subject = Some(subject);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder: Set body (for non-template emails)
|
||||
pub fn body(mut self, body: String) -> Self {
|
||||
self.body = Some(body);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl EmailClient {
|
||||
/// Create a new email client
|
||||
pub fn new() -> Self {
|
||||
@@ -198,6 +356,21 @@ impl EmailClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send a mail using a template
|
||||
pub fn send_mail(&self, mail: &Mail, template: &MailTemplate) -> Result<(), String> {
|
||||
// Render subject and body with parameters
|
||||
let subject = template.render_subject(&mail.parameters);
|
||||
let body_text = template.render_body(&mail.parameters);
|
||||
let html_body = template.render_html_body(&mail.parameters);
|
||||
|
||||
// Send email
|
||||
if let Some(html) = html_body {
|
||||
self.send_html_email(&mail.to, &subject, &html, Some(&body_text))
|
||||
} else {
|
||||
self.send_email(&mail.to, &subject, &body_text)
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a verification email with code
|
||||
pub fn send_verification_code_email(
|
||||
&self,
|
||||
|
||||
@@ -4,7 +4,7 @@ use ::rhai::plugin::*;
|
||||
use ::rhai::{CustomType, Dynamic, Engine, EvalAltResult, Module, TypeBuilder};
|
||||
|
||||
use super::verification::{Verification, VerificationStatus, VerificationTransport};
|
||||
use super::email::EmailClient;
|
||||
use super::email::{EmailClient, MailTemplate, Mail};
|
||||
|
||||
// ============================================================================
|
||||
// Verification Module
|
||||
@@ -107,6 +107,129 @@ mod rhai_verification_module {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Mail Template Module
|
||||
// ============================================================================
|
||||
|
||||
type RhaiMailTemplate = MailTemplate;
|
||||
|
||||
#[export_module]
|
||||
mod rhai_mail_template_module {
|
||||
use super::RhaiMailTemplate;
|
||||
use super::super::email::MailTemplate;
|
||||
use ::rhai::EvalAltResult;
|
||||
|
||||
#[rhai_fn(name = "new_mail_template", return_raw)]
|
||||
pub fn new_mail_template() -> Result<RhaiMailTemplate, Box<EvalAltResult>> {
|
||||
Ok(MailTemplate::new())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "id", return_raw)]
|
||||
pub fn set_id(
|
||||
template: &mut RhaiMailTemplate,
|
||||
id: String,
|
||||
) -> Result<RhaiMailTemplate, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(template);
|
||||
*template = owned.id(id);
|
||||
Ok(template.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "name", return_raw)]
|
||||
pub fn set_name(
|
||||
template: &mut RhaiMailTemplate,
|
||||
name: String,
|
||||
) -> Result<RhaiMailTemplate, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(template);
|
||||
*template = owned.name(name);
|
||||
Ok(template.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "subject", return_raw)]
|
||||
pub fn set_subject(
|
||||
template: &mut RhaiMailTemplate,
|
||||
subject: String,
|
||||
) -> Result<RhaiMailTemplate, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(template);
|
||||
*template = owned.subject(subject);
|
||||
Ok(template.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "body", return_raw)]
|
||||
pub fn set_body(
|
||||
template: &mut RhaiMailTemplate,
|
||||
body: String,
|
||||
) -> Result<RhaiMailTemplate, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(template);
|
||||
*template = owned.body(body);
|
||||
Ok(template.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "html_body", return_raw)]
|
||||
pub fn set_html_body(
|
||||
template: &mut RhaiMailTemplate,
|
||||
html_body: String,
|
||||
) -> Result<RhaiMailTemplate, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(template);
|
||||
*template = owned.html_body(html_body);
|
||||
Ok(template.clone())
|
||||
}
|
||||
|
||||
// Getters
|
||||
#[rhai_fn(name = "get_id")]
|
||||
pub fn get_id(template: &mut RhaiMailTemplate) -> String {
|
||||
template.id.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Mail Module
|
||||
// ============================================================================
|
||||
|
||||
type RhaiMail = Mail;
|
||||
|
||||
#[export_module]
|
||||
mod rhai_mail_module {
|
||||
use super::RhaiMail;
|
||||
use super::super::email::Mail;
|
||||
use ::rhai::EvalAltResult;
|
||||
|
||||
#[rhai_fn(name = "new_mail", return_raw)]
|
||||
pub fn new_mail() -> Result<RhaiMail, Box<EvalAltResult>> {
|
||||
Ok(Mail::new())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "to", return_raw)]
|
||||
pub fn set_to(
|
||||
mail: &mut RhaiMail,
|
||||
to: String,
|
||||
) -> Result<RhaiMail, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(mail);
|
||||
*mail = owned.to(to);
|
||||
Ok(mail.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "template", return_raw)]
|
||||
pub fn set_template(
|
||||
mail: &mut RhaiMail,
|
||||
template_id: String,
|
||||
) -> Result<RhaiMail, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(mail);
|
||||
*mail = owned.template(template_id);
|
||||
Ok(mail.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "parameter", return_raw)]
|
||||
pub fn add_parameter(
|
||||
mail: &mut RhaiMail,
|
||||
key: String,
|
||||
value: String,
|
||||
) -> Result<RhaiMail, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(mail);
|
||||
*mail = owned.parameter(key, value);
|
||||
Ok(mail.clone())
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Email Client Module
|
||||
// ============================================================================
|
||||
@@ -116,7 +239,9 @@ type RhaiEmailClient = EmailClient;
|
||||
#[export_module]
|
||||
mod rhai_email_module {
|
||||
use super::RhaiEmailClient;
|
||||
use super::super::email::EmailClient;
|
||||
use super::RhaiMail;
|
||||
use super::RhaiMailTemplate;
|
||||
use super::super::email::{EmailClient, Mail, MailTemplate};
|
||||
use super::super::verification::Verification;
|
||||
use ::rhai::EvalAltResult;
|
||||
|
||||
@@ -125,6 +250,86 @@ mod rhai_email_module {
|
||||
Ok(EmailClient::new())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "smtp_host", return_raw)]
|
||||
pub fn set_smtp_host(
|
||||
client: &mut RhaiEmailClient,
|
||||
host: String,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.smtp_host(host);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "smtp_port", return_raw)]
|
||||
pub fn set_smtp_port(
|
||||
client: &mut RhaiEmailClient,
|
||||
port: i64,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.smtp_port(port as u16);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "username", return_raw)]
|
||||
pub fn set_username(
|
||||
client: &mut RhaiEmailClient,
|
||||
username: String,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.username(username);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "password", return_raw)]
|
||||
pub fn set_password(
|
||||
client: &mut RhaiEmailClient,
|
||||
password: String,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.password(password);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "from_email", return_raw)]
|
||||
pub fn set_from_email(
|
||||
client: &mut RhaiEmailClient,
|
||||
email: String,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.from_address(email);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "from_name", return_raw)]
|
||||
pub fn set_from_name(
|
||||
client: &mut RhaiEmailClient,
|
||||
name: String,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.from_name(name);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "use_tls", return_raw)]
|
||||
pub fn set_use_tls(
|
||||
client: &mut RhaiEmailClient,
|
||||
use_tls: bool,
|
||||
) -> Result<RhaiEmailClient, Box<EvalAltResult>> {
|
||||
let owned = std::mem::take(client);
|
||||
*client = owned.use_tls(use_tls);
|
||||
Ok(client.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "send_mail", return_raw)]
|
||||
pub fn send_mail(
|
||||
client: &mut RhaiEmailClient,
|
||||
mail: RhaiMail,
|
||||
template: RhaiMailTemplate,
|
||||
) -> Result<(), Box<EvalAltResult>> {
|
||||
client.send_mail(&mail, &template)
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "send_verification_code", return_raw)]
|
||||
pub fn send_verification_code(
|
||||
client: &mut RhaiEmailClient,
|
||||
@@ -152,15 +357,25 @@ mod rhai_email_module {
|
||||
pub fn register_communication_modules(parent_module: &mut Module) {
|
||||
// Register custom types
|
||||
parent_module.set_custom_type::<Verification>("Verification");
|
||||
parent_module.set_custom_type::<MailTemplate>("MailTemplate");
|
||||
parent_module.set_custom_type::<Mail>("Mail");
|
||||
parent_module.set_custom_type::<EmailClient>("EmailClient");
|
||||
|
||||
// Merge verification functions
|
||||
let verification_module = exported_module!(rhai_verification_module);
|
||||
parent_module.merge(&verification_module);
|
||||
parent_module.combine_flatten(verification_module);
|
||||
|
||||
// Merge mail template functions
|
||||
let mail_template_module = exported_module!(rhai_mail_template_module);
|
||||
parent_module.combine_flatten(mail_template_module);
|
||||
|
||||
// Merge mail functions
|
||||
let mail_module = exported_module!(rhai_mail_module);
|
||||
parent_module.combine_flatten(mail_module);
|
||||
|
||||
// Merge email client functions
|
||||
let email_module = exported_module!(rhai_email_module);
|
||||
parent_module.merge(&email_module);
|
||||
parent_module.combine_flatten(email_module);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -173,6 +388,18 @@ impl CustomType for Verification {
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomType for MailTemplate {
|
||||
fn build(mut builder: TypeBuilder<Self>) {
|
||||
builder.with_name("MailTemplate");
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomType for Mail {
|
||||
fn build(mut builder: TypeBuilder<Self>) {
|
||||
builder.with_name("Mail");
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomType for EmailClient {
|
||||
fn build(mut builder: TypeBuilder<Self>) {
|
||||
builder.with_name("EmailClient");
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
use ::rhai::plugin::*;
|
||||
use ::rhai::{CustomType, Dynamic, Engine, EvalAltResult, Module, TypeBuilder};
|
||||
use std::mem;
|
||||
|
||||
use super::info::{KycInfo, VerificationStatus};
|
||||
use super::session::{KycSession, SessionStatus};
|
||||
use super::client::KycClient;
|
||||
|
||||
// ============================================================================
|
||||
// KYC Info Module
|
||||
@@ -290,6 +290,45 @@ mod rhai_kyc_session_module {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// KYC Client Module
|
||||
// ============================================================================
|
||||
|
||||
type RhaiKycClient = KycClient;
|
||||
|
||||
#[export_module]
|
||||
mod rhai_kyc_client_module {
|
||||
use super::RhaiKycClient;
|
||||
use super::RhaiKycInfo;
|
||||
use super::RhaiKycSession;
|
||||
use ::rhai::EvalAltResult;
|
||||
|
||||
#[rhai_fn(name = "new_kyc_client_idenfy", return_raw)]
|
||||
pub fn new_idenfy_client(
|
||||
api_key: String,
|
||||
api_secret: String,
|
||||
) -> Result<RhaiKycClient, Box<EvalAltResult>> {
|
||||
Ok(KycClient::idenfy(api_key, api_secret))
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "create_verification_session", return_raw)]
|
||||
pub fn create_verification_session(
|
||||
client: &mut RhaiKycClient,
|
||||
kyc_info: RhaiKycInfo,
|
||||
session: RhaiKycSession,
|
||||
) -> Result<String, Box<EvalAltResult>> {
|
||||
// Need to use tokio runtime for async call
|
||||
let rt = tokio::runtime::Runtime::new()
|
||||
.map_err(|e| format!("Failed to create runtime: {}", e))?;
|
||||
|
||||
let mut session_mut = session.clone();
|
||||
let url = rt.block_on(client.create_verification_session(&kyc_info, &mut session_mut))
|
||||
.map_err(|e| format!("Failed to create verification session: {}", e))?;
|
||||
|
||||
Ok(url)
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Registration Functions
|
||||
// ============================================================================
|
||||
@@ -299,6 +338,7 @@ pub fn register_kyc_modules(parent_module: &mut Module) {
|
||||
// Register custom types
|
||||
parent_module.set_custom_type::<KycInfo>("KycInfo");
|
||||
parent_module.set_custom_type::<KycSession>("KycSession");
|
||||
parent_module.set_custom_type::<KycClient>("KycClient");
|
||||
|
||||
// Merge KYC info functions
|
||||
let info_module = exported_module!(rhai_kyc_info_module);
|
||||
@@ -307,6 +347,10 @@ pub fn register_kyc_modules(parent_module: &mut Module) {
|
||||
// Merge KYC session functions
|
||||
let session_module = exported_module!(rhai_kyc_session_module);
|
||||
parent_module.merge(&session_module);
|
||||
|
||||
// Merge KYC client functions
|
||||
let client_module = exported_module!(rhai_kyc_client_module);
|
||||
parent_module.merge(&client_module);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -324,3 +368,9 @@ impl CustomType for KycSession {
|
||||
builder.with_name("KycSession");
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomType for KycClient {
|
||||
fn build(mut builder: TypeBuilder<Self>) {
|
||||
builder.with_name("KycClient");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user