183 lines
20 KiB
Plaintext
183 lines
20 KiB
Plaintext
<mxfile host="draw.io" modified="2026-02-12" agent="Claude Code" type="device">
|
|
<diagram id="a5-auth" name="Autoryzacja i OAuth">
|
|
<mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1600" pageHeight="1000" math="0" shadow="0">
|
|
<root>
|
|
<mxCell id="0"/>
|
|
<mxCell id="1" parent="0"/>
|
|
|
|
<mxCell id="title" value="NordaBiz — Autoryzacja, Role i OAuth 2.0" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=22;fontStyle=1;fontColor=#1a1a2e;" vertex="1" parent="1">
|
|
<mxGeometry x="400" y="15" width="530" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="subtitle" value="Hierarchia ról systemowych, uprawnienia firmowe i integracja OAuth z Google/Meta" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=11;fontColor=#888;" vertex="1" parent="1">
|
|
<mxGeometry x="380" y="48" width="560" height="20" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- ROLE SYSTEMOWE (lewa strona) -->
|
|
<mxCell id="roles_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E3F2FD;strokeColor=#1565C0;shadow=1;" vertex="1" parent="1">
|
|
<mxGeometry x="40" y="85" width="440" height="380" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="roles_title" value="<b style="font-size:16px;color:#1565C0">Role Systemowe (SystemRole)</b>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="55" y="91" width="300" height="26" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- Piramida ról -->
|
|
<mxCell id="r_admin" value="<b style="font-size:13px">ADMIN (100)</b><br><font style="font-size:9px">Pełna kontrola systemu<br>Zarządzanie użytkownikami</font>" style="trapezoid;whiteSpace=wrap;html=1;fillColor=#C62828;strokeColor=#C62828;fontColor=#fff;fontSize=11;perimeter=trapezoidPerimeter;fixedSize=1;size=20;" vertex="1" parent="1">
|
|
<mxGeometry x="160" y="125" width="200" height="50" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="r_office" value="<b style="font-size:12px">OFFICE_MANAGER (50)</b><br><font style="font-size:9px">Panel admina | Moderacja forum | Edycja firm</font>" style="trapezoid;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#E65100;fontColor=#fff;fontSize=11;perimeter=trapezoidPerimeter;fixedSize=1;size=15;" vertex="1" parent="1">
|
|
<mxGeometry x="130" y="180" width="260" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="r_manager" value="<b style="font-size:12px">MANAGER (40)</b><br><font style="font-size:9px">Pełna kontrola firmy | Zarządzanie pracownikami | Delegowanie uprawnień</font>" style="trapezoid;whiteSpace=wrap;html=1;fillColor=#F9A825;strokeColor=#F9A825;fontColor=#fff;fontSize=11;perimeter=trapezoidPerimeter;fixedSize=1;size=12;" vertex="1" parent="1">
|
|
<mxGeometry x="105" y="230" width="310" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="r_employee" value="<b style="font-size:12px">EMPLOYEE (30)</b><br><font style="font-size:9px">Edycja danych firmy (delegowane uprawnienia) | Ogłoszenia | Forum</font>" style="trapezoid;whiteSpace=wrap;html=1;fillColor=#2E7D32;strokeColor=#2E7D32;fontColor=#fff;fontSize=11;perimeter=trapezoidPerimeter;fixedSize=1;size=10;" vertex="1" parent="1">
|
|
<mxGeometry x="80" y="280" width="360" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="r_member" value="<b style="font-size:12px">MEMBER (20)</b><br><font style="font-size:9px">Kontakty firm | Forum | Chat AI | Ogłoszenia | Wiadomości</font>" style="trapezoid;whiteSpace=wrap;html=1;fillColor=#1565C0;strokeColor=#1565C0;fontColor=#fff;fontSize=11;perimeter=trapezoidPerimeter;fixedSize=1;size=8;" vertex="1" parent="1">
|
|
<mxGeometry x="60" y="330" width="400" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="r_unaffiliated" value="<b style="font-size:12px">UNAFFILIATED (10)</b><br><font style="font-size:9px">Tylko profile publiczne | Ograniczony chat AI | Brak kontaktów</font>" style="trapezoid;whiteSpace=wrap;html=1;fillColor=#9E9E9E;strokeColor=#9E9E9E;fontColor=#fff;fontSize=11;perimeter=trapezoidPerimeter;fixedSize=1;size=5;" vertex="1" parent="1">
|
|
<mxGeometry x="50" y="380" width="420" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="roles_arrow" value="<font style="font-size:10px;color:#1565C0">↑ has_role() = hierarchiczne<br>Wyższa rola = wszystkie<br>uprawnienia niższych</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="60" y="430" width="180" height="28" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- UPRAWNIENIA FIRMOWE (prawy-góra) -->
|
|
<mxCell id="comp_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E8F5E9;strokeColor=#2E7D32;shadow=1;" vertex="1" parent="1">
|
|
<mxGeometry x="530" y="85" width="380" height="200" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="comp_title" value="<b style="font-size:14px;color:#2E7D32">Role Firmowe (CompanyRole)</b>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="91" width="280" height="26" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="cr1" value="<b>MANAGER (30)</b> — pełna kontrola firmy + pracownicy" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#2E7D32;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="122" width="350" height="26" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="cr2" value="<b>EMPLOYEE (20)</b> — edycja danych (wg delegacji)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#2E7D32;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="154" width="350" height="26" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="cr3" value="<b>VIEWER (10)</b> — tylko odczyt dashboardu firmy" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#2E7D32;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="186" width="350" height="26" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="comp_note" value="<font style="font-size:10px;color:#2E7D32"><b>Multi-company:</b> user_companies (M:M)<br>Użytkownik może mieć różne role w różnych firmach</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="220" width="350" height="28" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- DELEGOWANE UPRAWNIENIA -->
|
|
<mxCell id="deleg_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF3E0;strokeColor=#E65100;shadow=1;" vertex="1" parent="1">
|
|
<mxGeometry x="530" y="300" width="380" height="165" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="deleg_title" value="<b style="font-size:14px;color:#E65100">Delegowane Uprawnienia</b><br><font style="font-size:10px">MANAGER → EMPLOYEE (user_company_permissions)</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="306" width="350" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="dp1" value="can_edit_description — opis, historia, wartości" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="346" width="350" height="22" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="dp2" value="can_edit_services — usługi, kompetencje, technologie" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="372" width="350" height="22" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="dp3" value="can_edit_contacts — email, telefon, adres" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="398" width="350" height="22" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="dp4" value="can_edit_social | can_manage_classifieds | can_post_forum | can_view_analytics" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="545" y="424" width="350" height="28" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- OAUTH 2.0 FLOW (dół) -->
|
|
<mxCell id="oauth_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F3E5F5;strokeColor=#7B1FA2;shadow=1;" vertex="1" parent="1">
|
|
<mxGeometry x="40" y="510" width="870" height="220" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="oauth_title" value="<b style="font-size:16px;color:#7B1FA2">OAuth 2.0 — Integracja z API Zewnętrznymi</b>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="55" y="516" width="400" height="26" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- OAuth flow steps -->
|
|
<mxCell id="of1" value="<b>1. Initiate</b><br><font style="font-size:9px">POST /api/oauth/<br>connect/{provider}<br>CSRF state token</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CE93D8;strokeColor=#7B1FA2;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="55" y="550" width="120" height="60" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="of2" value="<b>2. Redirect</b><br><font style="font-size:9px">User autoryzuje<br>na stronie Google/Meta</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CE93D8;strokeColor=#7B1FA2;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="195" y="550" width="120" height="60" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="of3" value="<b>3. Callback</b><br><font style="font-size:9px">GET /api/oauth/<br>callback/{provider}<br>Exchange code→token</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CE93D8;strokeColor=#7B1FA2;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="335" y="550" width="120" height="60" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="of4" value="<b>4. Save</b><br><font style="font-size:9px">oauth_tokens table<br>access + refresh<br>Auto-refresh on expiry</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CE93D8;strokeColor=#7B1FA2;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="475" y="550" width="120" height="60" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="ofa1" style="strokeColor=#7B1FA2;strokeWidth=2;" edge="1" source="of1" target="of2" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
|
|
<mxCell id="ofa2" style="strokeColor=#7B1FA2;strokeWidth=2;" edge="1" source="of2" target="of3" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
|
|
<mxCell id="ofa3" style="strokeColor=#7B1FA2;strokeWidth=2;" edge="1" source="of3" target="of4" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
|
|
|
|
<!-- OAuth providers -->
|
|
<mxCell id="google_oauth" value="<b style="color:#4285F4">Google OAuth ✅</b><br><font style="font-size:9px">GBP: business.manage<br>Search Console: webmasters<br><b>Działa na produkcji</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E3F2FD;strokeColor=#4285F4;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="630" y="548" width="130" height="65" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="meta_oauth" value="<b style="color:#1877F2">Meta OAuth ⏳</b><br><font style="font-size:9px">Facebook: pages_show_list<br>Instagram: instagram_basic<br><b>Framework gotowy</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E3F2FD;strokeColor=#1877F2;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="770" y="548" width="130" height="65" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- BEZPIECZEŃSTWO (prawy-dół) -->
|
|
<mxCell id="sec_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFEBEE;strokeColor=#C62828;shadow=1;" vertex="1" parent="1">
|
|
<mxGeometry x="40" y="640" width="870" height="90" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec_title" value="<b style="font-size:14px;color:#C62828">Zabezpieczenia</b>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="55" y="646" width="150" height="24" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec1" value="<b>Hasła</b><br><font style="font-size:9px">pbkdf2:sha256<br>8+ znaków</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="55" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec2" value="<b>2FA (TOTP)</b><br><font style="font-size:9px">Base32 + kody<br>zapasowe</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="165" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec3" value="<b>Brute-force</b><br><font style="font-size:9px">5 prób → 30 min<br>lockout</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="275" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec4" value="<b>CSRF</b><br><font style="font-size:9px">Flask-WTF +<br>OAuth state</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="385" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec5" value="<b>Rate Limit</b><br><font style="font-size:9px">50/h, 200/dzień<br>Flask-Limiter</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="495" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec6" value="<b>Email 24h</b><br><font style="font-size:9px">Weryfikacja +<br>reset token</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="605" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="sec7" value="<b>Audit Log</b><br><font style="font-size:9px">security_service<br>.log_audit()</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=10;" vertex="1" parent="1">
|
|
<mxGeometry x="715" y="674" width="100" height="45" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- DECORATORY -->
|
|
<mxCell id="dec_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E0F7FA;strokeColor=#00838F;shadow=1;" vertex="1" parent="1">
|
|
<mxGeometry x="960" y="85" width="280" height="380" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="dec_title" value="<b style="font-size:14px;color:#00838F">Dekoratory Flask</b><br><font style="font-size:10px">utils/decorators.py</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="91" width="200" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="d1" value="<b>@login_required</b><br><font style="font-size:9px">Flask-Login — redirect do /login</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#00838F;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="134" width="250" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="d2" value="<b>@role_required(SystemRole.X)</b><br><font style="font-size:9px">Minimalny poziom roli → 403</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#00838F;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="178" width="250" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="d3" value="<b>@admin_required</b><br><font style="font-size:9px">Alias: @role_required(ADMIN)</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#00838F;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="222" width="250" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="d4" value="<b>@member_required</b><br><font style="font-size:9px">Alias: @role_required(MEMBER)</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#00838F;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="266" width="250" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="d5" value="<b>@company_permission('edit')</b><br><font style="font-size:9px">Delegowane uprawnienia firmy</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#00838F;fontSize=10;align=left;spacingLeft=6;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="310" width="250" height="36" as="geometry"/>
|
|
</mxCell>
|
|
<mxCell id="dec_methods" value="<font style="font-size:10px;color:#00838F"><b>Metody User:</b><br>.has_role(SystemRole.X)<br>.can_edit_company(id)<br>.can_manage_company(id)<br>.can_access_admin_panel()<br>.has_delegated_permission()</font>" style="text;html=1;align=left;verticalAlign=top;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="975" y="358" width="200" height="86" as="geometry"/>
|
|
</mxCell>
|
|
|
|
<!-- PODSUMOWANIE -->
|
|
<mxCell id="summary" value="<font style="font-size:11px;color:#888"><b>6 ról systemowych</b> (hierarchiczne) | <b>3 role firmowe</b> (per company) | <b>7 delegowanych uprawnień</b> | <b>OAuth 2.0</b> (Google ✅ + Meta ⏳) | <b>7 zabezpieczeń</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
<mxGeometry x="250" y="760" width="820" height="24" as="geometry"/>
|
|
</mxCell>
|
|
|
|
</root>
|
|
</mxGraphModel>
|
|
</diagram>
|
|
</mxfile>
|