o
    sig(                     @   s  d dl mZmZmZmZmZmZmZmZ d dl	Z	d dl
Z
d dlZd dlmZ d dlZd dlZd dlZd dlmZ eeZdZdZdZdZd	Zd
ZdZdZdZdZdd Zdd Zdd Z dZ!dZ"dZ#e$ddd Z%e$de dd Z&e$de dd  Z'ej$d!d"gd#e d$d% Z(e$d&e d'd( Z)ej$d)d*d"gd#e d+d, Z*e$d-e d.d/ Z+e$d0d1d2 Z,e$d3d4d5 Z-e$d6e d7d8 Z.ej$d9d*d"gd#d:d; Z/d<d= Z0d>d? Z1d@dA Z2dBdC Z3dDdE Z4edFkrej5dGdHdI dS dS )J    )Flaskrequestrender_template_string	send_fileabortredirecturl_forResponseN)datetimewrapsz/opt/wgconfig/tokens.jsonz/opt/wgconfig/subnets.jsonz/opt/wgconfig/used_tokens.logz/opt/wgconfig/wg0-peers.confz/var/log/wg_keys_issued.logz/opt/wgconfig/backupsz,bsped9nemtP9fRfcVLoLL3JWTj7zHFYWJebAhgH7RFw=z24.249.187.133:51820adminchangemec                 C   s   | t ko|tkS N)ADMIN_USERNAMEADMIN_PASSWORD)usernamepassword r   &/var/www/wgsetup/wg_flask_token_app.py
check_auth      r   c                   C   s   t ddddiS )NzLogin Requiredi  zWWW-AuthenticatezBasic realm="Login Required")r	   r   r   r   r   authenticate   r   r   c                    s   t   fdd}|S )Nc                     s,   t j}|rt|j|jst S  | i |S r   )r   authorizationr   r   r   r   )argskwargsauthfr   r   	decorated!   s   z requires_auth.<locals>.decoratedr   )r   r   r   r   r   requires_auth    s   r    aU  
<!doctype html>
<title>WireGuard Config Generator</title>
<h2>WireGuard Config Generator</h2>
<p>Welcome, your token is valid. Click below to generate your secure config.</p>
<form method="post">
    <button type="submit">Generate My WireGuard Config</button>
</form>
<p><a href="/instructions" target="_blank">How to use this page</a></p>
un  
<!doctype html>
<title>WireGuard Setup Portal</title>
<h2>📜 Welcome to the WireGuard Setup Portal</h2>
<ol>
<li>Copy "<code>https://wgsetup.glorytoyah.org/setup?token=YourToken</code>" into the browser window.  Replace "YourToken" with your one-time token.  Ensure your one-time token is included on the line before going to step 2.</li>
<li>Click "Generate Config" to download your WireGuard config.  *Note where you are saving your config file.</li>
<li>Import it into the WireGuard app (mobile or desktop)</li>
<li>DO NOT LOAD THE SAME CONFIGURATION FILE ON MORE THAN ONE DEVICE.  For multiple devices ... Repeat steps 1 -3 for each device.</li>
</ol>
<p>
<a href="/setup?token=example-token"><button>🔐 Generate Config</button></a>
<a href="/admin/guide"><button>📘 Admin Guide</button></a>
<a href="/admin/tokens"><button>🎛️ Token Dashboard</button></a>
</p>

u  
<!doctype html>
<title>Admin Guide</title>
<h2>Admin Guide</h2>
<ul>
  <li>📦 <strong>Token Creation</strong>: Use /generate-and-redirect/&lt;GroupName&gt; to generate a token.</li>
  <li>🔐 <strong>Access Token Panel</strong>: Visit /admin/tokens to manage tokens.</li>
  <li>🗃 <strong>Used Tokens</strong>: View /admin/used for audit logs of used/revoked tokens.</li>
  <li>🧰 <strong>Subnet Setup</strong>: Add or modify group subnets via /admin/subnets.</li>
  <li>💾 <strong>Backup</strong>: Download backups from /admin/backup.</li>
  <li>♻️ <strong>Restore</strong>: Unzip a backup and move files into /opt/wgconfig.</li>
</ul>
<h3>Common Issues:</h3>
<ul>
  <li>🚫 <strong>Permission denied?</strong> Ensure correct file permissions (e.g., chown www-data).</li>
  <li>❌ <strong>WireGuard fails to reload?</strong> Check for duplicate IPs or malformed entries.</li>
</ul>
<h3>FAQs:</h3>
<ul>
  <li><strong>Can a token be reused?</strong> No. Tokens are removed after use.</li>
  <li><strong>Can I edit peer configs manually?</strong> Yes, but ensure unique IPs and public keys.</li>
</ul>
<p><a href="/"><button>🏠 Back to Home</button></a></p>
z/generate-and-redirect/<group>c                    s   t  }t }|vrdS |   fdd| D }dt| }  d| d}t|r>|d7 }  d| d}t|s.tt }|d||< t| t	t
d	|d
S )N)zInvalid group namei  c                    s4   g | ]}| d kr| dd r|d qS )groupip )get
startswith).0databaser!   r   r   
<listcomp>f   s   4 z)generate_and_redirect.<locals>.<listcomp>   .z/24   )r"   r!   setup)token)load_tokensload_subnetsvalueslen	ip_in_usestruuiduuid4save_tokensr   r   )r!   tokenssubnetsused	next_hostnew_ipr/   r   r(   r   generate_and_redirect_   s    r>   z/admin/tokensc                  C   sZ   t  } d}|  D ]\}}|d| d|d  d|d  d| d	7 }q	|d7 }|d	7 }|S )
Nzg<h2>Active Tokens</h2><table border='1'><tr><th>Token</th><th>IP</th><th>Group</th><th>Revoke</th></tr><tr><td>	</td><td>r"   r!   z </td><td><a href='/admin/revoke/z'>Revoke</a></td></tr>zh</table><form method='post' action='/admin/tokens/purge'><button type='submit'>Purge All</button></form>z<p><a href='/admin/used'>View Used</a> | <a href='/admin/subnets'>Subnets</a> | <a href='/admin/backup'>Backup</a> | <a href='/admin/guide'>Admin Guide</a></p><a href='/'><button> Back to Home</button></a></p>)r0   items)r9   htmltvr   r   r   admin_tokensq   s   ,rE   z/admin/revoke/<token>c                 C   sr   t  }| |v r3ttd}|d|  d||   d W d    n1 s%w   Y  ||  t| ttdS )Naz
[REVOKED]  - 
rE   )r0   openUSED_LOG_PATHwritepopr8   r   r   )r/   r9   logr   r   r   revoke_token|   s   
rN   z/admin/tokens/purgePOST)methodsc                   C   s   t tdd ttdS )Nwz{}rE   )rI   TOKEN_DB_PATHrK   r   r   r   r   r   r   purge_tokens   s   rS   z/admin/usedc                  C   sL   t jtsdS tt} d|   dW  d    S 1 sw   Y  d S )Nu}   <p>No used tokens logged.</p><p><a href='/admin/tokens'>Back</a></p><p><a href='/'><button>🏠 Back to Home</button></a></p>z!<h2>Used/Revoked Tokens</h2><pre>uf   </pre><p><a href='/admin/tokens'>Back</a></p><p><a href='/'><button>🏠 Back to Home</button></a></p>)ospathexistsrJ   rI   readr   r   r   r   	view_used   s
   
$rX   z/admin/subnetsGETc                  C   s   t  } tjdkr tjd}tjd}|r |r || |< t|  d}|  D ]\}}|d| d| d7 }q&|d7 }|d	7 }|S )
NrO   namer)   zH<h2>Subnets</h2><table border='1'><tr><th>Group</th><th>Subnet</th></tr>r?   r@   z
</td></tr>zl</table><form method='post'>Group: <input name='name'> Base: <input name='base'> <button>Add</button></form>uj   <p><a href='/admin/tokens'>Back to Tokens</a></p><p><a href='/'><button>🏠 Back to Home</button></a></p>)r1   r   methodformr$   save_subnetsrA   )r:   rZ   r)   rB   krD   r   r   r   manage_subnets   s   
r_   z/admin/backupc                  C   sT   t jtdd t d} t jtd|  d}t	|
dddd t|dd	S )
NT)exist_okz%Y%m%d_%H%M%Sbackup_z.zipr#   zipz/opt/wgconfigas_attachment)rT   makedirs
BACKUP_DIRr
   nowstrftimerU   joinshutilmake_archivereplacer   )	timestampzip_pathr   r   r   
backup_all   s
   ro   /c                   C      t tS r   r   HTML_INSTRUCTIONSr   r   r   r   homepage      rt   z/instructionsc                   C   rq   r   rr   r   r   r   r   instructions   ru   rv   z/admin/guidec                   C   rq   r   )r   HTML_ADMIN_GUIDEr   r   r   r   admin_guide   s   rx   z/setupc                  C   s  t jd} t }| |vrtdddS ||  d }t jdkrBztddg 	 }tjdd	g|
 d
 	 }W n tyT } zd| dfW  Y d }~S d }~ww d| d| dt dt d	}t }tj|d|  d}t|d}	|	| W d    n1 sw   Y  ttd}
|
dt  d|  d| d| d	 W d    n1 sw   Y  d| d|dd  d}ttd}|| W d    n1 sw   Y  ztjd dd!d"tgd#tjd$ W n  tjy } ztjd%|j    W Y d }~nd }~ww tt!d}|d&|  d'||   d( W d    n	1 s.w   Y  |"|  t#| t$|d#d)S t%t&S )*Nr/   i  zInvalid or missing token.)descriptionr"   rO   wggenkeypubkey)inputzKey generation failed: i  z
[Interface]
PrivateKey = z
Address = z

[Peer]
PublicKey = z
Endpoint = z1
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
client_z.confrQ   rF   [z] z -> z (z)
z
[Peer]
PublicKey = z
AllowedIPs = rp   r   z/32
sudoaddconfwg0T)checkstderrz(Failed to update live WireGuard config: z[USED] rG   rH   rc   )'r   r   r$   r0   r   r[   
subprocesscheck_outputdecodestripencode	ExceptionSERVER_PUBLIC_KEYSERVER_ENDPOINTtempfilemkdtemprT   rU   ri   rI   rK   KEY_LOG_PATHr
   rg   splitPEERS_CONF_PATHrunPIPECalledProcessErrorapploggererrorr   rJ   rL   r8   r   r   	HTML_FORM)r/   r9   assigned_ipprivate_key
public_keyeconfigtemp_dirconfig_pathr   rM   
peer_entrypeerconfr;   r   r   r   r.      s^   "* $
r.   c                  C   B   t jtrtt} t| W  d    S 1 sw   Y  i S r   )rT   rU   rV   rR   rI   jsonloadr   r   r   r   r0      
   
 r0   c                 C   @   t td}tj| |dd W d    d S 1 sw   Y  d S NrQ   r+   )indent)rI   rR   r   dump)r9   r   r   r   r   r8         "r8   c                  C   r   r   )rT   rU   rV   SUBNET_DB_PATHrI   r   r   r   r   r   r   r1      r   r1   c                 C   r   r   )rI   r   r   r   )r:   r   r   r   r   r]      r   r]   c                 C   sR   t jtsdS tt}| dd | v W  d    S 1 s"w   Y  d S )NFrp   r   )rT   rU   rV   r   rI   r   rW   )r"   r   r   r   r   r4      s
   
$r4   __main__z0.0.0.0i  )hostport)6flaskr   r   r   r   r   r   r   r	   rT   r   r   r
   rj   r   r6   	functoolsr   __name__r   rR   r   rJ   r   r   rf   r   r   r   r   r   r   r    r   rs   rw   router>   rE   rN   rS   rX   r_   ro   rt   rv   rx   r.   r0   r8   r1   r]   r4   r   r   r   r   r   <module>   s~   ( 	
		


+