From 5614a714bc184daa8eabbc969637852db404a94b Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 28 Oct 2025 04:58:10 +0000 Subject: [PATCH] 1.1 fix --- config/__pycache__/__init__.cpython-311.pyc | Bin 159 -> 159 bytes config/__pycache__/settings.cpython-311.pyc | Bin 4210 -> 4210 bytes config/__pycache__/urls.cpython-311.pyc | Bin 1143 -> 1143 bytes config/__pycache__/wsgi.cpython-311.pyc | Bin 679 -> 679 bytes core/__pycache__/__init__.cpython-311.pyc | Bin 157 -> 157 bytes core/__pycache__/admin.cpython-311.pyc | Bin 777 -> 1179 bytes core/__pycache__/apps.cpython-311.pyc | Bin 524 -> 524 bytes core/__pycache__/forms.cpython-311.pyc | Bin 847 -> 523 bytes core/__pycache__/models.cpython-311.pyc | Bin 1409 -> 2180 bytes core/__pycache__/urls.cpython-311.pyc | Bin 347 -> 447 bytes core/__pycache__/views.cpython-311.pyc | Bin 2006 -> 3020 bytes core/admin.py | 17 +- core/forms.py | 7 +- ...application_vulnerability_delete_ticket.py | 39 +++ .../__pycache__/0001_initial.cpython-311.pyc | Bin 1660 -> 1660 bytes ...ulnerability_delete_ticket.cpython-311.pyc | Bin 0 -> 2452 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 168 -> 168 bytes core/models.py | 51 ++-- core/templates/base.html | 69 +++++ core/templates/core/article_detail.html | 14 + core/templates/core/index.html | 252 +++++++----------- core/templates/core/upload_inventory.html | 13 + core/urls.py | 7 +- core/views.py | 73 ++--- static/css/custom.css | 46 ++++ 25 files changed, 371 insertions(+), 217 deletions(-) create mode 100644 core/migrations/0002_application_vulnerability_delete_ticket.py create mode 100644 core/migrations/__pycache__/0002_application_vulnerability_delete_ticket.cpython-311.pyc create mode 100644 core/templates/base.html create mode 100644 core/templates/core/article_detail.html create mode 100644 core/templates/core/upload_inventory.html create mode 100644 static/css/custom.css diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 3d6501c67fa5c80fdda8a8ee57862699aabd319d..1be7e5044c1e21b55394c3388160096a477de7d5 100644 GIT binary patch delta 19 ZcmbQwIG>SwIWI340}$Nc`!|t$3IHv(1uFmm delta 19 ZcmbQwIG>SwIWI340}vQ{ewxTV1pq3~1hoJF diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index dadfaa7db630a06a9bc0da9edbc375273aefa0ed..c0aca8ac3378767753c3a6bd580e918fc14ec20e 100644 GIT binary patch delta 20 acmeyQ@JWGtIWI340}$Nc`?rxhT>t<>#Rd`p delta 20 acmeyQ@JWGtIWI340}wn|@_i$Bx&Q!2UIwWE diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 139db1071801d00bd7e1a167305bffd074d952f6..81ed005ace9b35576c3e2e02e0f244b1c1dbf4ac 100644 GIT binary patch delta 20 acmey)@tuQvIWI340}$Nc`?rxhhXnvZAqC|C delta 20 acmey)@tuQvIWI340}vQ{e%i>L!vX+3#075v diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index 79ce690f602e05f6bfa8a8e253edcb377296b788..0628b0100696cf4e393ccd9def5226fcd6675392 100644 GIT binary patch delta 20 acmZ3^x}24JIWI340}$Nc`?ryM4if-1GX-q` delta 20 acmZ3^x}24JIWI340}vQ{e%i=AhY0{N)&%ze diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 3b7774ea363dc0bd4dc92284fe89acea2051acd3..9fe0af5f301ed38928f3645b475d73a2d0ada25e 100644 GIT binary patch delta 19 ZcmbQsIG2%oIWI340}$Nc`!|t$5&$i11tkCg delta 19 ZcmbQsIG2%oIWI340}vQ{ewxTV2>>dE1g`)9 diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 5e41572949c7873f8ad5478be4973869ac513d51..65fbd5aae57948da5501e2ff8bad2714c72dba0f 100644 GIT binary patch literal 1179 zcma)5y-wUf5Z?74hQs`m1Oy~X5#)lqJU|kODn$YfQVKVg@h)KEpUbXILU#oZKu4Z{ zDB>|9r3UGW(^g2S=ng?eie$!z(Gjl5+WUETXXcyTZ`R)&XM{kTXMc8nQ$l{>q-xgf z;OZv~jtC=+#w4L0rG#lrkF`Yi^u+KCN;Jahu2}_g{TR4Tp!b?a-V$aU5N3i`#Y&EK z@PXcI$M89+Cd3>1htU|oXaVEUe>2+5-XQMq1?F(6G6R-G=>_i5)l_Y@*^Hww$fGP( z&W9pSxd=9+ILi0KyG_BMI?~l6m>dyKJj#ftG3x0|^9-g#3PVlwv8`enS64wZ~JI30D)tz$9t_>#nJ6-$y^+S0lckWUPpBJnH+OiXgtVjK-17eHO`P9PBGc z@<4<;{#L|eCcl#_U?Mjwjh!svjbgJ%^P<7O@UX};(fFK+kFptryb)%CH%bZW&3$3x z9uN%Z@(Doe?m3@+*?QlZdC^+KM@&_&gLRn)^B`S3lNq3msiy9U+f&C>R=CIgh^bo8 zR|i{ikPAwnESU#+A(aEC4l`Kf%nx!`7r0e12cRbVB6}i&wpb-qV_b$JYGQ5IT}zB& zjDs+SFkbqUnr=mL&V`u3)%T!k~3`SdFpW zAl=UDVV341+7x){l?CPHu@v~%2>dCOE%-K+mJ2nqhPG0iUTwJVsvz{W_sR)LxJbERxxV-GmyKsh*2WL)gi<^cXEW1rT~2v4fo z%4PP4Z>YMH5oQ=2HAtNcBjhfRLSeNS4H)GYBG1TqL_$s&BECyKVb>XPIl;)~j>bl% zH&YusIZq z3Pxmx3lieL=#L-7JH5hkyxp7Fh<8=6;%|S=F%zPf)`i8$i8Lil*t-EHUi!Y&l1-@Q zbYfDnFKbn<5qV^d%}J?#D7;EK`n*5e0sn3v=Hue^;;r!lr@C S-qYeoitjqmriYHDyL0#ks&dbZi00cMq{%z!DWC8#$*94jX delta 20 acmeBS>0#ks&dbZi00hRKpEhzcG64WAdITf@ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index f6e5c4e3024d0f534a8b93046d15a44a0c8eeba6..7e82c9aa98ffbcc3a5d9db5f267498d8a1ae4422 100644 GIT binary patch literal 523 zcmZutJx{|h5IyIkDou+R5o&)xBp?$K1A+yWi7u!T%3_7sr7cNaoJPRbfq{X60jd9> z2=&iUiJ|h!#1>ShE?_4O5`wdRe$RLJ?DJElQUYmH^3^_-`2>8M$;{?oNr1x0tzl7;A$FB zy=&x&V+kfX0oNo*s%m1j*$YaerrEtS8h$6;4FQgcY62>7TaiDM+BID8>nVzMR(#(oPi{f6^ o$Ua|_6v-7GOPA;fp&6{d{GN${P%VMK?xFeUeyH=$e}d_C-vs`4l>h($ literal 847 zcmZ`%v2N5r5S{hfzRN+lAV`E#KtsV5#6N(jP>?`L1C<-g@op}@*yqcxEl8IlMM?^! z^b|peKcTwvv@KP-i!P$LiWx5^vXsp3KF{pTzS)`e_tn)NpbVe?IrxR&-()o6{Zkfi zP&o$yf@P4ikTDRB;F**2kTY=LEeQ7%geTd^Z4O^>fSAzHjZ`y3>MOhD+=$rvVcE*wmN%Sy-v#{{nFS*~s5Z}Byei_I3F z4*}q}f+L2|9q#a%Djbu`qzLH0k)TLCB%;PjO-HA#Im6pfmo{&0G z>7-1H@$SGk-6$Hzxr`#yi=w;`RYv;#C_1X*%z6}c*m&raneq2inF;*^7F5ylWpGgB zGN|^daajfOvrMY8P{F4{9qLJ($RH_{4C*#+O^%IAH&rWmk~sBKgp>bcwzhHR%^tp+ z*7MA#p&nz1+CbPHxat8JeS)=STRkGJj#?+J(*V7U-bT1dFn1j9J)6VrcvbIT-{G|> zh@HCTi%~ot7K;8HqAz{&S2JAd&%rB zA88Lh^uVD94oFl=D@8p}qHy5YL;rvt*U}!Wy;iEk%@H|qN#E>Z2&U@8`)1yoH*em& zdGE*XqS%Fidhv(ljW9xgGoek9lgZIDnCu{oFsGv`SK>GnLemI`engljTqV@ru*)O# z7QTQ=yl)i-tH}RYg|SdXx#%I=l;b?1YG9(9>WLG7XuCXm3E~bSsKjAZ3WX5iD-d)* znA;ESau5J~0hJ;h7W@SZp~K>$k0^!ZmF8Zs(lzJ^1~Mf6;@P6T5fBLN4UuUQCu*T(azS$uju2 zbv94R@(WwhgB8l|>&3^H6*{F69n%EJG|800Dyd=5rtVGO|-hQf(dg!V4XNjOt%OE|V4@94NxhtDn& z#)S~; zL8s`HRTit~8Lhlb`vO6jCs?zq^lBjTbH*CI#^!7*Um$Drda#llQ=iw2HJ#ux!L;93 z9w#2vhQ6UjnG(~aHv+@hV`3WmDj0nRio^TB7IGmPh0zo2n)bpbhYaf4x~RHrXeu$i z^y){kYs7>A;zmsd5F!@wl9cF*MX+D>hgonCM8^A`>F3OS6q6;z)-Aw-qyl{?L%_0v zG03sDd=3;?5Bs3N-rzhaKsvbsY!uX0B5Rnk*A99H}qlNF}@tLn5jZYT6RB>T!;YqPA`#nrAu?=~) zA-+J?Ex((+1SY0RwG{?|Ud$u_Q1Iqn*AyU*R<6yG4Zo4S==fN1d~9OUODJcU=?SK# zShnej6Oh#ftx5u?BGydR09TM{#qyH6Vp_7jf?4W)w4j$+EN6i6DH9oE&0+on>XO&bE?~UZy!=^+GF!06=`KkPaps@j*j;;EE6GQ%&jS)-6}M*^mZZX|O)q zO!sfDy6OJC`_32BPI{)1o^jJN^_iwL!0ZNI&;Bv;=R@aP&5EPL4 zPaLt>5R0x@1n1d1TT^cK&H;9^qmAsSn;ossH#4`lM%>KpgRGMoX=GqJQlDd>)yF`q zlLaYY7cb-@UL04HTG`0s#Q=08^X#8zfTn(i&S&j7_GJLs59wFnft8`T0j$My9M?ow ro%6p|Sl|FTFS4y$+xOlv{rj`U?#mp+dXa5SZO^@9`uG2_=-=jF?_&b6 literal 1409 zcmZuxy>Ht_6hDg8w@169EsumE? zlf`$Pzf%bPA&e=dC(6Y#C~pu!M6yv&(j^I{&?+LSSBS_|>Ox*Z$1*~vuoBW`qHLo^ z`dpX|iD!Bap|)#I;8pCw%enF6V#5KVV8(?lYlDaR0h3M(N! zdnF=GWs*6|UO7;1CQ2c>nW%gm6}Ls~ehlk0DFa+D#%O8kxPq!NTArdLe^$71(#lLk z@k+!TDZN5^m8j6XGS6t1`ILGMxsl?EGoXF0Yyk(WX!Y@cIc-K=_eF8Nf9v7I04!tL zj!Oy8ti&?TmThOB%ilTs0`E~``8}T5h^5%OW3@Y6Sp$Cl51bzcR_GZA*rxrq*Ezoi zE+!_>kXa1`&zc>_GO5e6gzg!>?J*VH8l;sB-*a%^*~bPUVCSZ`c{wkL6uNjS7jwYg zpqHo%G9kFPv*Wc|@(*sp;slDfloLldkt&Y>9Eq~YVdwz=^P!sC0*1p4@x&y*<-+HvJJ)U})xF652bPRUiqBdb4 z3OnO^hUdFHH(-{-Eblol-0K;Z9f$A=qtATmdX!-*ygaYb124gfgt{iP2A<{gx%!Ra zQO)Yn1S^<~f`eeg;{|^}COVsklD{Ih0D|2RO#I?vCJyKR4lKC*j8jTIGe%PuY>rFH zb>Wz>P`NfPp~}s}y{P=r$;V;2IV?A$ax+*RsSAfYk-BhFd;8?Kolw<=surnQaDN2R zKShZ-yTf`TsyBkIQSJ88CsFP8u(lZ07K3j` z)jLP^sCwt^QdnIcR+ppda`0g4Jn_Qn(y+P|RhNPXV?|2OkI^hk?k%po*-&_%bd7%7 zX_DP!GU*NRhm>^WQ_+^oF1^ovnGF3a_89=;-MJgU#n3W_bVr diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 4e4f113d309e34129cca5a1bb3778fb33b4fe2e4..732b20f1579c557077014bdf1530162fc1221f99 100644 GIT binary patch literal 447 zcmZurJx{|h5Ix6E`lYG}u^=(BM4;vmKqh7uCc=Q++BAhEj-0rqOdb0V;1_@p{1T>A z>QH4uLJZw1b?X97TLuu%XZz0Yo!>px>s8SBWMBT9zCViM2i7K8csjWU1`GudA`c;8 z2E&07Vh@MJBM1!Oh!KvN`D#64fET^jSTQ9|Sots0F+7u1&cLqD3aO2964TV5p`tMI z3ZseN5>&E$OT~ep?6Mp6c$5k`$U&N$mWYP@uCx|7vKaZ)w(=Ugrcp;Ul?)PD%#xeE zF7GF+wv{TcX-@m4Tt>+=EVKrehmJ2o?x>cEQswYl-d5Vq=?i(2#I((wwvd|EpEl#c zvV0T@rULHDhHfs#POkJZ#|WV*>}9{>9h%vHF}J|13{OVeqw|N0jM!shPl!DwW&O6B a?d)d<#~E?Q#GMd#ZsLY9tQAYvwbeKEcz1FD delta 230 zcmdnbe4D9$IWI340}w2<{FRXfq#uJgFu)3Be6|5HrZc24q%h_%v9u+`Ev0AML{Zyy(R}T%9x2?U_e11*cezj8(cbs fIznc!U0{*F$RdA*Mg9Xb6F*Y}HwYH-05t;uGa@lf diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 9d0ddd892cc8db8e347c5f97af5002a4ce469452..aa5727c22ea517742836bf330077c797da979209 100644 GIT binary patch literal 3020 zcmbVOO>7&-6`tk(kQ7OA`KKS-GHFS+OO+C>xN%yc{r0&@ZH8Jr8s!iQ+COZI~d$^0zJ2A<0j$U>RwU~gbJ!8OxxB2YQo&LUokZ@JG+n`khpMJpkFpHu{>idt6y!-&Qzi{u zoRR2T%>olaEc~DU8CoABtJx0ErIz1zb9zU55!wN3uhp`_SVGHq)pvd0@-Eko*w$ob z-?sy~?Y&xl>?@7I?sNag7~Hq4AK%WttsPrGzRZ+;Wwy+fd6}1mEn!2jB5m(7lKo|2 z2li@@?w406IA%!THdZazeGT?HU@9vLn2!iMqpU)MU|I#MWUi+=P?4FH3Oax!E0DNl zSOsmq&_<9+Qip9TM}VX%Ch3!24m5wfC!s5=-)IbX#0)QEV+k-juNR8SdQ>v7l2-xF zYh#O6QOo)PAdheiR*I1N!~B=c_|D(K7D87DS;5F4q*M(kM5iRCIks>jn# z{Nh1;v=$$=<9R2Zul%^48gx=42dVK|YW(R$H8pOhCY{veL29~|nzmCjPHLtyQx^vu z@%(|9tBJYK?^eZ}ElxP%#DRFDCf=~cTaI|EGF4BUbrKg25+k+5h@HqeiCks6A)s{D zJ(qKbUvtynar=hdzI-F%j|vS0qVnbo5ryNM7ptdpy9;*ciW9n0<*q!3380fn;x|A9 zk5L&dQ5Ubs%=;cWY%;jtY5@~bpB8C=-s;(b*1cBG22*CXPdwzEhXemRNF%nQ$iDt& z0%*f$g<1w$YLQUcw?y~DD>5r{GQThEz*u{&@itg1*7N|n3pVvK+j;aiI4jlcgP9#8 z1_oO0pr7B{;H}=a7aUgp59p7_h>Ag0U)yJ?b-cH`+pTR4h#=6OCs@G_tE+A8hdPOY zK_5?96p=5B9PXUaEE+;qrrC?oFv70`-5kw7QWj3iANK3WnzbXq?bUpvV}}{^0B*Pq z;R8YMJ$$Y*t7wgVfL0m3`zT^McO0&h^X=$Be%*4k%&1J~Jb?hk8N$8u_UyZa1C~(M z`I7bC==TYbhPt2w$7ER&P;|+VRegc@fdVvDSBRisY+!R;dfjFy z^2lR3$Pq5!Y=Q_y#ac9E9H65Of*}0l)b!n15>U^rR~1C|CSw{aH10*ac(I3$<<$9{nho4uQyOEc!O#9#K;ZCJw3Q} zb+^YkeQ7gLPoHzr`OgD?iTu-FeekoYtX0!RJ6&|r#m#WN|IF5@?P*)0+cM{;Hlh(?C8* z{-~^rscKJt_a+Faws^@AFIB}$u9$q>{k!fbR`vX~r{f@?+TwLbyk7lA{R&Ehr-7-G zri=9A0us;K(X8F-qZYJiYMu;iqTq&^;$~ugcvs>E8bJ)`iDQJA>>O zqu;$V!2V-^2R$1mqP$el7mP7;(ZCj5bEb!hL(B+80Dxv5Ldv^?d5T=~5U`gaFdnCZ zQjE9bpCO!~It9hofgi%_B~7`8Z-Ys{(#&6iXs`^!xM;L`QgzW-^`z>ebJfo3qOOYf bb5XG3{TiIeywN}{G2F{c!6uw6y*&R1KYGM) literal 2006 zcmZ`(&2Q936d!wcz21)`&W4tJ#pJA?V%j1zOmzNm$ozG=l3ywe)Hb% z%?~3Zc?9FF3q=E*-j z479_0?hBiOCEO9YnTVF?30CU9NR#Y?c5QI}H@-|+=}nR529D9No${FX$C{LI!+SPU zn*tq6Z168R;jN4%Z9`N$QDj{EKl`$8?z7~_^8GZONIW6PmX+H~57!dvm~Wk5i3+CD z8de>{vutlw4NQWur#5X`Qyt%cda7VivA1p$-*d4?RSQ$Yc7kfFXw>UXyVcsLn!d~A zi}m`KTw=LPjzJxN)iztXW!zM6(hUc*i5n}|uPiRy(m!3ixv;WyYhaWLKH(DYNaRP^~=u`nh_pqn_KE-I{$i*}l4) zFFl<5w)(KzUg%5c(6R8~%x?K)w>;Y`&+e9Idgb@K67l%h2GSK{&;Ro>LVcS%fBB$#nRS^&g9(F)o$TzuW+`L zKD!4&B9oJ3Bu%z=8Z?g(M*ND?L<|=k&S;V)Xju_q*%G&*sdomAt>vr~Ksn8n_|o|M zZfPBi(nO=1MF&vBofDNaO4Twisve%7U0!$``60Z5tPnIz69)lD(vOH71syrU$$JUmQZNUkJ(yv!)Lsn7 zC)-!T1E<>8!qVZbx$oAyrQ^NQ@%B|dV@KRaWr9p`SMLI0QrruKXD>#g5^JhK%_kIq z6GQ-Hg?%+d6~uuS6Agt{j`4hGUll_OS`HK2tYXWiB+LJn;b#xxJV;Saf+#^zM&kpX z;(-hf{aXGw&g*&d0T_7If)GeQB?v-@a_wk_XsjL0m*{k7c!lU_XLyC^SZ8>J=tyUH tg~Lw3=Swuz8D1eOcZOGAQiKotXh4pqg%f@BZ?e_;m1}?d4^wpVzX0UP4AcMs diff --git a/core/admin.py b/core/admin.py index 639ff3a..6fe1e89 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,8 +1,13 @@ from django.contrib import admin -from .models import Ticket +from .models import Application, Vulnerability -@admin.register(Ticket) -class TicketAdmin(admin.ModelAdmin): - list_display = ('subject', 'status', 'priority', 'requester_email', 'created_at') - list_filter = ('status', 'priority') - search_fields = ('subject', 'requester_email', 'description') +@admin.register(Application) +class ApplicationAdmin(admin.ModelAdmin): + list_display = ('name', 'version', 'vendor') + search_fields = ('name', 'vendor') + +@admin.register(Vulnerability) +class VulnerabilityAdmin(admin.ModelAdmin): + list_display = ('cve_id', 'application', 'severity', 'status', 'discovered_at') + list_filter = ('severity', 'status', 'application__name') + search_fields = ('cve_id', 'description') \ No newline at end of file diff --git a/core/forms.py b/core/forms.py index 7a6b83b..21e602d 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,7 +1,4 @@ from django import forms -from .models import Ticket -class TicketForm(forms.ModelForm): - class Meta: - model = Ticket - fields = ['subject', 'requester_email', 'priority', 'description'] +class UploadFileForm(forms.Form): + file = forms.FileField() \ No newline at end of file diff --git a/core/migrations/0002_application_vulnerability_delete_ticket.py b/core/migrations/0002_application_vulnerability_delete_ticket.py new file mode 100644 index 0000000..fce2355 --- /dev/null +++ b/core/migrations/0002_application_vulnerability_delete_ticket.py @@ -0,0 +1,39 @@ +# Generated by Django 5.2.7 on 2025-10-27 12:23 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Application', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('version', models.CharField(max_length=100)), + ('vendor', models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name='Vulnerability', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cve_id', models.CharField(max_length=50, unique=True)), + ('description', models.TextField()), + ('severity', models.CharField(choices=[('Critical', 'Critical'), ('High', 'High'), ('Medium', 'Medium'), ('Low', 'Low')], max_length=10)), + ('status', models.CharField(choices=[('New', 'New'), ('Acknowledged', 'Acknowledged'), ('In-Progress', 'In-Progress'), ('Resolved', 'Resolved')], default='New', max_length=20)), + ('discovered_at', models.DateTimeField(auto_now_add=True)), + ('last_updated', models.DateTimeField(auto_now=True)), + ('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vulnerabilities', to='core.application')), + ], + ), + migrations.DeleteModel( + name='Ticket', + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc index 64d8a5533a01aeb9823459fa0e2a5787563687ab..487e6cd3e17526168ad7f92c1c7b8f22e62d3023 100644 GIT binary patch delta 20 acmeyv^M{9fIWI340}$Nc`?rz1kPQGrdj8$ZEL1Fqvd>@)<-BMw1OQC!qCCczX?RYKZYs#Y7%;B2zqHM8r4 zAfa;Tp+|1b5%rL&!Uv8y^uV#FYAx--np35oax)?)F7%(-IB_0_cGmmvKl6X{zh~s% zqS255;|lt)^p`9M|FB7C^z1V43c&m#AOZPwq2z)~)g`mVe^AlXo?d*~Z*% zNkqPiuOx{A_U~IlB4R7@a&Jcg^25`EKtW1epZn07^9m4^|em4sk5+BW4Ud8$OcLkt3M&5ln_-!X1Zk zWI5X5m!UVkv3z2WJK5pTDEg!^cG#~<;Mn}f_I90Vj34x&B9-FkEcEF)8obx(PiR(u z*(8`oCMPE^E1IF%nySbil6x~S=zy-wxwDpoYKJ;l_Cq>n@EhW5CQX&7OvOtcz1cr;*P zP!C(Oeh4x!11tojlOev5`fqEMB{J+yCs(`DsA21AjFo+&3zC&+&@>ddtgsCwBv@w}y%LJHN#%L1yn?|2UZ4BfJ{nNC zR8eS1QQ(@Z>lpZmqCBpvIx9MxAzXvHVxtU33A-|Bc!synJ$5e=c74&vms({S8f%u7 zoCar>RI}ZtB8o%Sqj6rf#^Y8%`|W z4)*k)X!ityp|=8%9Y)%H`_82QgERZ8$(u1JHP=kdxv4oPb{k@G(vvS`H$B-*Pr2zS zCw8S3PdP)EHWu8WOKm~;v?v~;3*vWdY505bEvGx2!b-d(c0~aTS5*e=rYmBNEj<%| zWS_w=Bv1hqQ~-sQ__WlDr=8JjFUQ@{Yi|n9Xt6n3bVrL$>`p5_;$*JAJnd$#ZrM(z z(99IvOu>oW;z3+yL0sON{iEpS@4ESiZvF>He+DXN#D~mQW`Vg26l?)yw!RhH@gU1> zgyj~<4kPV>{oE#@_)G?5hmm$}pih2&hdtz0r*X0}O?pi}ffgsce-sm)PA4}3MuU5D ze#-d4@;a};v~X3kz`YOTy`y@Q6k*E#8d!@!+LF)bgKqR?93k!fTEaQ!xL;dN`{cH8 Sl)MPJv9Y&Iuyc%*`|vMa6^d5? literal 0 HcmV?d00001 diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index 58b1c14eb06fea9cfb9a0d59788218572a75b51c..1b471530ad4b8e8569c4f26a75cf28639c3ac0de 100644 GIT binary patch delta 19 ZcmZ3%xPp;;IWI340}$Nc`!|t$E&wkB1x5e> delta 19 ZcmZ3%xPp;;IWI340}vQ{ewxTV7XU0A1keBg diff --git a/core/models.py b/core/models.py index 78b60d1..e1ff649 100644 --- a/core/models.py +++ b/core/models.py @@ -1,25 +1,34 @@ from django.db import models -class Ticket(models.Model): - STATUS_CHOICES = [ - ('open', 'Open'), - ('in_progress', 'In Progress'), - ('closed', 'Closed'), - ] - - PRIORITY_CHOICES = [ - ('low', 'Low'), - ('medium', 'Medium'), - ('high', 'High'), - ] - - subject = models.CharField(max_length=255) - status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='open') - priority = models.CharField(max_length=20, choices=PRIORITY_CHOICES, default='medium') - requester_email = models.EmailField() - description = models.TextField() - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) +class Application(models.Model): + name = models.CharField(max_length=255) + version = models.CharField(max_length=100) + vendor = models.CharField(max_length=255) def __str__(self): - return self.subject \ No newline at end of file + return f"{self.name} {self.version}" + +class Vulnerability(models.Model): + SEVERITY_CHOICES = [ + ('Critical', 'Critical'), + ('High', 'High'), + ('Medium', 'Medium'), + ('Low', 'Low'), + ] + STATUS_CHOICES = [ + ('New', 'New'), + ('Acknowledged', 'Acknowledged'), + ('In-Progress', 'In-Progress'), + ('Resolved', 'Resolved'), + ] + + cve_id = models.CharField(max_length=50, unique=True) + description = models.TextField() + severity = models.CharField(max_length=10, choices=SEVERITY_CHOICES) + application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='vulnerabilities') + status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='New') + discovered_at = models.DateTimeField(auto_now_add=True) + last_updated = models.DateTimeField(auto_now=True) + + def __str__(self): + return self.cve_id diff --git a/core/templates/base.html b/core/templates/base.html new file mode 100644 index 0000000..d486179 --- /dev/null +++ b/core/templates/base.html @@ -0,0 +1,69 @@ + + + + + + {% block title %}{{ project_name|default:"Vulnerability Scanner" }}{% endblock %} + + + {% load static %} + + + + +
+ + + + + +
+ + +
+ {% block content %}{% endblock %} +
+
+ +
+ + + + + + \ No newline at end of file diff --git a/core/templates/core/article_detail.html b/core/templates/core/article_detail.html new file mode 100644 index 0000000..8820990 --- /dev/null +++ b/core/templates/core/article_detail.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} + +{% block title %}{{ article.title }}{% endblock %} + +{% block content %} +
+

{{ article.title }}

+

Published on {{ article.created_at|date:"F d, Y" }}

+
+
+ {{ article.content|safe }} +
+
+{% endblock %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index f4e4991..6a0a55d 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,157 +1,107 @@ - - +{% extends 'base.html' %} +{% load static %} - - - - {{ project_name }} - {% if project_description %} - - - - {% endif %} - {% if project_image_url %} - - - {% endif %} - - - - - - - -
-
-

Analyzing your requirements and generating your website…

-
- Loading… +
+
+
+
+
+
+
{{ total_applications }}
+
Total Applications
+
+ +
+
-

Appwizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} — - UTC {{ current_time|date:"Y-m-d H:i:s" }} -

-
- Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC) -
-
- +
+
+
+
+
+
{{ total_vulnerabilities }}
+
Total Vulnerabilities
+
+ +
+
+
+
+
+
+
+
+
+
{{ critical_vulnerabilities }}
+
Critical Vulnerabilities
+
+ +
+
+
+
+
+
+
+
+
+
{{ new_vulnerabilities }}
+
New Vulnerabilities
+
+ +
+
+
+
+ - \ No newline at end of file +
+
+
+ + Application Inventory +
+ Upload Inventory +
+
+
+ + + + + + + + + + + {% for app in applications %} + + + + + + + {% empty %} + + + + {% endfor %} + +
NameVersionVendorActions
{{ app.name }}{{ app.version }}{{ app.vendor }} + +
No applications found.
+
+
+
+ + +{% endblock %} diff --git a/core/templates/core/upload_inventory.html b/core/templates/core/upload_inventory.html new file mode 100644 index 0000000..3a0d6c1 --- /dev/null +++ b/core/templates/core/upload_inventory.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block content %} +
+

Upload Application Inventory

+

Upload a CSV file with the following columns: Name, Version, Vendor.

+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+{% endblock %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..048e0b9 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,8 @@ from django.urls import path -from .views import home +from .views import dashboard, upload_inventory urlpatterns = [ - path("", home, name="home"), -] + path("", dashboard, name="dashboard"), + path("upload/", upload_inventory, name="upload_inventory"), +] \ No newline at end of file diff --git a/core/views.py b/core/views.py index c1a6d45..4525723 100644 --- a/core/views.py +++ b/core/views.py @@ -1,37 +1,48 @@ -import os -import platform +from django.shortcuts import render, redirect +from .models import Application, Vulnerability +from .forms import UploadFileForm +import csv +import io -from django import get_version as django_version -from django.shortcuts import render -from django.urls import reverse_lazy -from django.utils import timezone -from django.views.generic.edit import CreateView - -from .forms import TicketForm -from .models import Ticket - - -def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" - now = timezone.now() +def dashboard(request): + # Placeholder data + total_apps = Application.objects.count() + total_vulns = Vulnerability.objects.count() + critical_vulns = Vulnerability.objects.filter(severity='Critical').count() + new_vulns = Vulnerability.objects.filter(status='New').count() + applications = Application.objects.all() context = { - "project_name": "New Style", - "agent_brand": agent_brand, - "django_version": django_version(), - "python_version": platform.python_version(), - "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), - "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), + 'total_applications': total_apps, + 'total_vulnerabilities': total_vulns, + 'critical_vulnerabilities': critical_vulns, + 'new_vulnerabilities': new_vulns, + 'applications': applications, + "project_name": "Vulnerability Scanner", } return render(request, "core/index.html", context) - -class TicketCreateView(CreateView): - model = Ticket - form_class = TicketForm - template_name = "core/ticket_create.html" - success_url = reverse_lazy("home") +def upload_inventory(request): + if request.method == 'POST': + form = UploadFileForm(request.POST, request.FILES) + if form.is_valid(): + try: + csv_file = request.FILES['file'] + decoded_file = io.TextIOWrapper(csv_file.file, encoding='utf-8', newline='', errors='ignore') + reader = csv.reader(decoded_file) + # Skip header row + next(reader) + for row in reader: + print(f"Processing row: {row}") + Application.objects.create( + name=row[0], + version=row[1], + vendor=row[2], + ) + return redirect('dashboard') + except Exception as e: + print(f"An error occurred: {e}") + form.add_error(None, f"An error occurred: {e}") + else: + form = UploadFileForm() + return render(request, 'core/upload_inventory.html', {'form': form}) diff --git a/static/css/custom.css b/static/css/custom.css new file mode 100644 index 0000000..b4e4285 --- /dev/null +++ b/static/css/custom.css @@ -0,0 +1,46 @@ +body { + overflow-x: hidden; +} + +#sidebar-wrapper { + min-height: 100vh; + margin-left: -15rem; + transition: margin .25s ease-out; +} + +#sidebar-wrapper .sidebar-heading { + padding: 0.875rem 1.25rem; + font-size: 1.2rem; + font-weight: bold; +} + +#sidebar-wrapper .list-group { + width: 15rem; +} + +#page-content-wrapper { + min-width: 100vw; +} + +#wrapper.toggled #sidebar-wrapper { + margin-left: 0; +} + +@media (min-width: 768px) { + #sidebar-wrapper { + margin-left: 0; + } + + #page-content-wrapper { + min-width: 0; + width: 100%; + } + + #wrapper.toggled #sidebar-wrapper { + margin-left: -15rem; + } +} + +.card-body .fs-1 { + opacity: 0.7; +}