Spaces:
Paused
Paused
| import streamlit as st | |
| import pandas as pd | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| import numpy as np | |
| from datetime import datetime, timedelta | |
| def render_monitoring(): | |
| st.title("Monitoring Configuration") | |
| # Dashboard layout for monitoring configuration | |
| col1, col2 = st.columns([2, 3]) | |
| with col1: | |
| st.subheader("Monitoring Settings") | |
| with st.form("monitoring_settings"): | |
| st.markdown("### General Settings") | |
| scan_frequency = st.select_slider( | |
| "Scan Frequency", | |
| options=["1 hour", "2 hours", "4 hours", "6 hours", "12 hours", "24 hours"], | |
| value="4 hours" | |
| ) | |
| intelligence_sources = st.multiselect( | |
| "Intelligence Sources", | |
| ["Dark Web Forums", "Paste Sites", "Marketplaces", "Telegram Channels", "IRC Channels", "Ransomware Blogs", "Breach Databases", "Hacker Forums", "Social Media"], | |
| default=["Dark Web Forums", "Paste Sites", "Marketplaces", "Ransomware Blogs"] | |
| ) | |
| st.markdown("### Alert Thresholds") | |
| col1a, col1b = st.columns(2) | |
| with col1a: | |
| critical_threshold = st.number_input("Critical Alert Threshold", min_value=1, max_value=100, value=80) | |
| with col1b: | |
| high_threshold = st.number_input("High Alert Threshold", min_value=1, max_value=100, value=60) | |
| col1c, col1d = st.columns(2) | |
| with col1c: | |
| medium_threshold = st.number_input("Medium Alert Threshold", min_value=1, max_value=100, value=40) | |
| with col1d: | |
| low_threshold = st.number_input("Low Alert Threshold", min_value=1, max_value=100, value=20) | |
| st.markdown("### Notification Channels") | |
| email_notify = st.checkbox("Email Notifications", value=True) | |
| if email_notify: | |
| email_recipients = st.text_input("Email Recipients", value="security@company.com, analyst@company.com") | |
| slack_notify = st.checkbox("Slack Notifications", value=True) | |
| if slack_notify: | |
| slack_channel = st.text_input("Slack Channel", value="#security-alerts") | |
| api_notify = st.checkbox("API Webhook", value=False) | |
| if api_notify: | |
| webhook_url = st.text_input("Webhook URL", placeholder="https://api.example.com/webhook") | |
| sms_notify = st.checkbox("SMS Notifications", value=False) | |
| if sms_notify: | |
| phone_numbers = st.text_input("Phone Numbers", placeholder="+1234567890, +0987654321") | |
| submit = st.form_submit_button("Save Configuration", type="primary") | |
| if submit: | |
| st.success("Monitoring configuration saved successfully!") | |
| with col2: | |
| st.subheader("Monitored Keywords & Entities") | |
| # Tabs for different monitoring categories | |
| tab1, tab2, tab3, tab4 = st.tabs(["Company Assets", "Credentials", "PII", "Custom Keywords"]) | |
| with tab1: | |
| st.markdown("### Company Assets Monitoring") | |
| # Sample company assets to monitor | |
| company_assets = pd.DataFrame({ | |
| "Asset Type": ["Domain", "Domain", "IP Range", "Brand", "Brand", "Product", "Technology"], | |
| "Value": ["company.com", "company-services.net", "198.51.100.0/24", "CompanyName", "ProductX", "ServiceY", "TechnologyZ"], | |
| "Priority": ["High", "Medium", "High", "Critical", "High", "Medium", "Low"], | |
| "Status": ["Active", "Active", "Active", "Active", "Active", "Active", "Active"] | |
| }) | |
| # Editable dataframe | |
| edited_assets = st.data_editor( | |
| company_assets, | |
| num_rows="dynamic", | |
| column_config={ | |
| "Asset Type": st.column_config.SelectboxColumn( | |
| "Asset Type", | |
| options=["Domain", "IP Range", "Brand", "Product", "Technology", "Other"], | |
| ), | |
| "Priority": st.column_config.SelectboxColumn( | |
| "Priority", | |
| options=["Critical", "High", "Medium", "Low"], | |
| ), | |
| "Status": st.column_config.SelectboxColumn( | |
| "Status", | |
| options=["Active", "Paused"], | |
| ), | |
| }, | |
| use_container_width=True | |
| ) | |
| with tab2: | |
| st.markdown("### Credentials Monitoring") | |
| # Sample credential monitoring settings | |
| credential_monitoring = pd.DataFrame({ | |
| "Email Domain": ["@company.com", "@company-services.net", "@product-x.com"], | |
| "Include Subdomains": [True, True, False], | |
| "Monitor Password Breach": [True, True, True], | |
| "Alert Level": ["Critical", "High", "High"], | |
| "Status": ["Active", "Active", "Active"] | |
| }) | |
| edited_credentials = st.data_editor( | |
| credential_monitoring, | |
| num_rows="dynamic", | |
| column_config={ | |
| "Include Subdomains": st.column_config.CheckboxColumn( | |
| "Include Subdomains", | |
| help="Monitor all subdomains", | |
| ), | |
| "Monitor Password Breach": st.column_config.CheckboxColumn( | |
| "Monitor Password Breach", | |
| ), | |
| "Alert Level": st.column_config.SelectboxColumn( | |
| "Alert Level", | |
| options=["Critical", "High", "Medium", "Low"], | |
| ), | |
| "Status": st.column_config.SelectboxColumn( | |
| "Status", | |
| options=["Active", "Paused"], | |
| ), | |
| }, | |
| use_container_width=True | |
| ) | |
| with tab3: | |
| st.markdown("### PII Monitoring") | |
| # Sample PII monitoring settings | |
| pii_monitoring = pd.DataFrame({ | |
| "PII Type": ["SSN", "Credit Card", "Bank Account", "Passport Number", "Driver License"], | |
| "Monitor": [True, True, True, False, False], | |
| "Alert Level": ["Critical", "Critical", "High", "High", "Medium"], | |
| "Status": ["Active", "Active", "Active", "Paused", "Paused"] | |
| }) | |
| edited_pii = st.data_editor( | |
| pii_monitoring, | |
| num_rows="dynamic", | |
| column_config={ | |
| "PII Type": st.column_config.SelectboxColumn( | |
| "PII Type", | |
| options=["SSN", "Credit Card", "Bank Account", "Passport Number", "Driver License", "Health Information", "Other"], | |
| ), | |
| "Monitor": st.column_config.CheckboxColumn( | |
| "Monitor", | |
| ), | |
| "Alert Level": st.column_config.SelectboxColumn( | |
| "Alert Level", | |
| options=["Critical", "High", "Medium", "Low"], | |
| ), | |
| "Status": st.column_config.SelectboxColumn( | |
| "Status", | |
| options=["Active", "Paused"], | |
| ), | |
| }, | |
| use_container_width=True | |
| ) | |
| with tab4: | |
| st.markdown("### Custom Keywords") | |
| # Sample custom keywords | |
| custom_keywords = pd.DataFrame({ | |
| "Keyword": ["confidential memo", "project phoenix", "merger", "acquisition", "layoff", "security breach"], | |
| "Category": ["Internal Document", "Project", "Financial", "Financial", "HR", "Security"], | |
| "Alert Level": ["Critical", "High", "Critical", "Critical", "High", "Critical"], | |
| "Status": ["Active", "Active", "Active", "Active", "Active", "Active"] | |
| }) | |
| edited_keywords = st.data_editor( | |
| custom_keywords, | |
| num_rows="dynamic", | |
| column_config={ | |
| "Category": st.column_config.SelectboxColumn( | |
| "Category", | |
| options=["Internal Document", "Project", "Financial", "HR", "Security", "Product", "Other"], | |
| ), | |
| "Alert Level": st.column_config.SelectboxColumn( | |
| "Alert Level", | |
| options=["Critical", "High", "Medium", "Low"], | |
| ), | |
| "Status": st.column_config.SelectboxColumn( | |
| "Status", | |
| options=["Active", "Paused"], | |
| ), | |
| }, | |
| use_container_width=True | |
| ) | |
| # Monitoring sources and coverage | |
| st.markdown("---") | |
| st.subheader("Monitoring Sources & Coverage") | |
| # Create tabs for different monitoring source categories | |
| source_tab1, source_tab2, source_tab3 = st.tabs(["Dark Web Coverage", "Source Categories", "Geographic Coverage"]) | |
| with source_tab1: | |
| # Dark web monitoring sources | |
| st.markdown("### Dark Web Monitoring Sources") | |
| # Sample data for dark web sources | |
| dark_web_sources = pd.DataFrame({ | |
| "Source Type": ["Market", "Forum", "Forum", "Market", "Paste Site", "Leak Site", "Chat", "Market"], | |
| "Name": ["AlphaBay", "XSS Forum", "Exploit.in", "ASAP Market", "DeepPaste", "DarkLeak", "Telegram", "White House"], | |
| "Focus": ["General", "Hacking", "Credentials", "Drugs/Fraud", "Text sharing", "Data leaks", "Communication", "General"], | |
| "Coverage": [95, 90, 85, 80, 75, 70, 65, 60], | |
| "Status": ["Active", "Active", "Active", "Active", "Active", "Active", "Active", "Active"] | |
| }) | |
| fig = px.bar( | |
| dark_web_sources, | |
| x="Name", | |
| y="Coverage", | |
| color="Coverage", | |
| color_continuous_scale=["#2ECC71", "#F1C40F", "#E74C3C"], | |
| text="Coverage", | |
| height=400 | |
| ) | |
| fig.update_layout( | |
| paper_bgcolor='rgba(26, 26, 26, 0)', | |
| plot_bgcolor='rgba(26, 26, 26, 0)', | |
| xaxis=dict( | |
| title=None, | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| yaxis=dict( | |
| title="Coverage Percentage", | |
| showgrid=True, | |
| gridcolor='rgba(44, 62, 80, 0.3)', | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| coloraxis_showscale=False | |
| ) | |
| fig.update_traces(texttemplate='%{text}%', textposition='outside') | |
| st.plotly_chart(fig, use_container_width=True) | |
| # Source details table | |
| st.dataframe(dark_web_sources, use_container_width=True) | |
| with source_tab2: | |
| # Source category distribution | |
| st.markdown("### Monitoring by Source Category") | |
| # Sample data for source categories | |
| source_categories = { | |
| "Category": ["Dark Web Markets", "Hacking Forums", "Paste Sites", "Telegram Channels", "IRC Channels", "Leak Sites", "Ransomware Blogs", "Social Media"], | |
| "Sources Count": [12, 15, 5, 18, 8, 7, 6, 10], | |
| "Coverage Score": [90, 85, 75, 70, 60, 95, 80, 65] | |
| } | |
| source_df = pd.DataFrame(source_categories) | |
| fig = px.scatter( | |
| source_df, | |
| x="Sources Count", | |
| y="Coverage Score", | |
| color="Coverage Score", | |
| color_continuous_scale=["#E74C3C", "#F1C40F", "#2ECC71"], | |
| size="Sources Count", | |
| hover_name="Category", | |
| height=400 | |
| ) | |
| fig.update_layout( | |
| paper_bgcolor='rgba(26, 26, 26, 0)', | |
| plot_bgcolor='rgba(26, 26, 26, 0)', | |
| xaxis=dict( | |
| title="Number of Sources", | |
| showgrid=True, | |
| gridcolor='rgba(44, 62, 80, 0.3)', | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| yaxis=dict( | |
| title="Coverage Score (%)", | |
| showgrid=True, | |
| gridcolor='rgba(44, 62, 80, 0.3)', | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| coloraxis_showscale=False | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| # Category details | |
| st.dataframe(source_df, use_container_width=True) | |
| with source_tab3: | |
| # Geographic coverage | |
| st.markdown("### Geographic Monitoring Coverage") | |
| # World map showing coverage | |
| st.image("https://images.unsplash.com/photo-1451187580459-43490279c0fa", | |
| caption="Global monitoring coverage across dark web sources", | |
| use_column_width=True) | |
| # Regional coverage metrics | |
| col_geo1, col_geo2, col_geo3, col_geo4 = st.columns(4) | |
| with col_geo1: | |
| st.metric( | |
| label="North America", | |
| value="92%", | |
| delta="3%", | |
| delta_color="normal" | |
| ) | |
| with col_geo2: | |
| st.metric( | |
| label="Europe", | |
| value="88%", | |
| delta="5%", | |
| delta_color="normal" | |
| ) | |
| with col_geo3: | |
| st.metric( | |
| label="Asia Pacific", | |
| value="76%", | |
| delta="8%", | |
| delta_color="normal" | |
| ) | |
| with col_geo4: | |
| st.metric( | |
| label="Rest of World", | |
| value="65%", | |
| delta="12%", | |
| delta_color="normal" | |
| ) | |
| # Monitoring performance metrics | |
| st.markdown("---") | |
| st.subheader("Monitoring Performance") | |
| # Performance metrics | |
| perf_col1, perf_col2, perf_col3, perf_col4 = st.columns(4) | |
| with perf_col1: | |
| st.metric( | |
| label="Scan Completion Rate", | |
| value="98.7%", | |
| delta="0.5%", | |
| delta_color="normal" | |
| ) | |
| with perf_col2: | |
| st.metric( | |
| label="Avg. Scan Duration", | |
| value="43 min", | |
| delta="-7 min", | |
| delta_color="normal" | |
| ) | |
| with perf_col3: | |
| st.metric( | |
| label="Monitored Keywords", | |
| value="1,247", | |
| delta="23", | |
| delta_color="normal" | |
| ) | |
| with perf_col4: | |
| st.metric( | |
| label="Coverage Index", | |
| value="87/100", | |
| delta="5", | |
| delta_color="normal" | |
| ) | |
| # Performance charts | |
| st.markdown("### Performance Trends") | |
| perf_tab1, perf_tab2 = st.tabs(["Scan Performance", "Detection Accuracy"]) | |
| with perf_tab1: | |
| # Generate dates for the past 30 days | |
| dates = [(datetime.now() - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(30, 0, -1)] | |
| # Sample data for scan performance | |
| scan_times = np.random.normal(45, 5, 30).astype(int) # Mean 45 minutes, std 5 minutes | |
| success_rates = np.random.normal(98, 1, 30) # Mean 98%, std 1% | |
| success_rates = [min(100, max(90, rate)) for rate in success_rates] # Clamp between 90-100% | |
| scan_data = pd.DataFrame({ | |
| 'Date': dates, | |
| 'Scan Time (min)': scan_times, | |
| 'Success Rate (%)': success_rates | |
| }) | |
| # Create a figure with two y-axes | |
| fig = go.Figure() | |
| # Add scan time line | |
| fig.add_trace(go.Scatter( | |
| x=scan_data['Date'], | |
| y=scan_data['Scan Time (min)'], | |
| name='Scan Time (min)', | |
| line=dict(color='#3498DB', width=2) | |
| )) | |
| # Add success rate line on secondary y-axis | |
| fig.add_trace(go.Scatter( | |
| x=scan_data['Date'], | |
| y=scan_data['Success Rate (%)'], | |
| name='Success Rate (%)', | |
| line=dict(color='#2ECC71', width=2), | |
| yaxis='y2' | |
| )) | |
| # Configure the layout with two y-axes | |
| fig.update_layout( | |
| paper_bgcolor='rgba(26, 26, 26, 0)', | |
| plot_bgcolor='rgba(26, 26, 26, 0)', | |
| xaxis=dict( | |
| title="Date", | |
| showgrid=False, | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| yaxis=dict( | |
| title="Scan Time (min)", | |
| showgrid=True, | |
| gridcolor='rgba(44, 62, 80, 0.3)', | |
| tickfont=dict(color='#ECF0F1'), | |
| range=[0, 60] | |
| ), | |
| yaxis2=dict( | |
| title="Success Rate (%)", | |
| showgrid=False, | |
| tickfont=dict(color='#ECF0F1'), | |
| overlaying='y', | |
| side='right', | |
| range=[90, 100] | |
| ), | |
| legend=dict( | |
| orientation="h", | |
| yanchor="bottom", | |
| y=1.02, | |
| xanchor="right", | |
| x=1, | |
| font=dict(color='#ECF0F1') | |
| ), | |
| height=400 | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| with perf_tab2: | |
| # Sample data for detection accuracy | |
| accuracy_data = pd.DataFrame({ | |
| 'Date': dates, | |
| 'True Positives': np.random.randint(80, 100, 30), | |
| 'False Positives': np.random.randint(5, 15, 30), | |
| 'Precision': np.random.normal(92, 2, 30), | |
| 'Recall': np.random.normal(90, 3, 30) | |
| }) | |
| # Ensure precision and recall are within reasonable bounds | |
| accuracy_data['Precision'] = accuracy_data['Precision'].apply(lambda x: min(100, max(80, x))) | |
| accuracy_data['Recall'] = accuracy_data['Recall'].apply(lambda x: min(100, max(80, x))) | |
| # Create a figure with stacked bars and lines | |
| fig = go.Figure() | |
| # Add stacked bars for true and false positives | |
| fig.add_trace(go.Bar( | |
| x=accuracy_data['Date'], | |
| y=accuracy_data['True Positives'], | |
| name='True Positives', | |
| marker_color='#2ECC71' | |
| )) | |
| fig.add_trace(go.Bar( | |
| x=accuracy_data['Date'], | |
| y=accuracy_data['False Positives'], | |
| name='False Positives', | |
| marker_color='#E74C3C' | |
| )) | |
| # Add lines for precision and recall | |
| fig.add_trace(go.Scatter( | |
| x=accuracy_data['Date'], | |
| y=accuracy_data['Precision'], | |
| name='Precision (%)', | |
| line=dict(color='#3498DB', width=2), | |
| yaxis='y2' | |
| )) | |
| fig.add_trace(go.Scatter( | |
| x=accuracy_data['Date'], | |
| y=accuracy_data['Recall'], | |
| name='Recall (%)', | |
| line=dict(color='#F1C40F', width=2), | |
| yaxis='y2' | |
| )) | |
| # Configure the layout | |
| fig.update_layout( | |
| paper_bgcolor='rgba(26, 26, 26, 0)', | |
| plot_bgcolor='rgba(26, 26, 26, 0)', | |
| barmode='stack', | |
| xaxis=dict( | |
| title="Date", | |
| showgrid=False, | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| yaxis=dict( | |
| title="Alert Count", | |
| showgrid=True, | |
| gridcolor='rgba(44, 62, 80, 0.3)', | |
| tickfont=dict(color='#ECF0F1') | |
| ), | |
| yaxis2=dict( | |
| title="Percentage (%)", | |
| showgrid=False, | |
| tickfont=dict(color='#ECF0F1'), | |
| overlaying='y', | |
| side='right', | |
| range=[80, 100] | |
| ), | |
| legend=dict( | |
| orientation="h", | |
| yanchor="bottom", | |
| y=1.02, | |
| xanchor="right", | |
| x=1, | |
| font=dict(color='#ECF0F1') | |
| ), | |
| height=400 | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |