#2 feature/change-admin-auth-method

Merged
tovi merged 5 commits from feature/change-admin-auth-method into develop 3 years ago
  1. +19
    -1
      Variables/Variables.go.sample
  2. +54
    -19
      Webserver/Admin.go
  3. +25
    -2
      Webserver/Index.go
  4. +16
    -9
      Webserver/Post.go
  5. +11
    -6
      Webserver/ServeFile.go
  6. +3
    -0
      Webserver/Webserver.go
  7. +3
    -1
      web/css/main.css
  8. +3
    -0
      web/html/error.gohtml
  9. +1
    -1
      web/html/header.gohtml
  10. +11
    -4
      web/html/index-intro.gohtml
  11. +8
    -0
      web/html/index-links.gohtml
  12. +7
    -0
      web/html/index.gohtml
  13. +0
    -57
      web/html/links.html
  14. +6
    -1
      web/html/post.gohtml
  15. BIN
      web/static/1622082948272.jpg
  16. BIN
      web/static/favicon-16x16.png
  17. BIN
      web/static/favicon-32x32.png
  18. BIN
      web/static/favicon.ico

+ 19
- 1
Variables/Variables.go.sample View File

@ -1,14 +1,32 @@
package Variables package Variables
import (
"github.com/gorilla/sessions"
)
const ( const (
ProjectRoot string = "/path/to/project/root" ProjectRoot string = "/path/to/project/root"
DbHost string = "localhost" DbHost string = "localhost"
DbPort int = 5432 DbPort int = 5432
DbName string = "personal-website"
DbName string = "db"
DbUser string = "postgres" DbUser string = "postgres"
DbPass string = "" DbPass string = ""
DbOpts string = "sslmode=disable" DbOpts string = "sslmode=disable"
WebserverHost string = ":8080" WebserverHost string = ":8080"
AdminUsername string = "tovi"
// Generate password with bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
AdminPassword string = "$2a$04$Q.FgFAfUfqezReI3JyStD.VP8KdjB6UXc8s.PgTgflLG/2yFq.4Hi"
)
var (
DefaultSidebarLinks = map[string]string{
"Email": "mailto:email@example.com",
}
CookieKey = []byte("super-secret-key")
CookieStore = sessions.NewCookieStore(CookieKey)
CookieName string = "someones-blog-auth"
) )

+ 54
- 19
Webserver/Admin.go View File

@ -14,16 +14,17 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"golang.org/x/crypto/bcrypt"
) )
func CheckAuth(w http.ResponseWriter, r *http.Request) bool { func CheckAuth(w http.ResponseWriter, r *http.Request) bool {
var ( var (
session *sessions.Session
lastActiveUnix int64
lastActive time.Time
auth bool
exists bool
e error
session *sessions.Session
lastLoginUnix int64
lastLogin time.Time
auth bool
exists bool
e error
) )
session, e = Variables.CookieStore.Get(r, Variables.CookieName) session, e = Variables.CookieStore.Get(r, Variables.CookieName)
if e != nil { if e != nil {
@ -35,14 +36,14 @@ func CheckAuth(w http.ResponseWriter, r *http.Request) bool {
return false return false
} }
lastActiveUnix, exists = session.Values["lastActive"].(int64)
lastLoginUnix, exists = session.Values["lastLogin"].(int64)
if !exists { if !exists {
return false return false
} }
lastActive = time.Unix(lastActiveUnix, 0)
lastLogin = time.Unix(lastLoginUnix, 0)
lastLogin = lastLogin.Add(3 * time.Hour)
lastActive.Add(12 * time.Hour)
if time.Now().Before(lastActive) {
if time.Now().After(lastLogin) {
session.Values = make(map[interface{}]interface{}) session.Values = make(map[interface{}]interface{})
session.Values["authenticated"] = false session.Values["authenticated"] = false
session.AddFlash("Login Expired") session.AddFlash("Login Expired")
@ -54,13 +55,6 @@ func CheckAuth(w http.ResponseWriter, r *http.Request) bool {
return false return false
} }
session.Values["lastLogin"] = time.Now().Unix()
e = session.Save(r, w)
if e != nil {
log.Println(e.Error())
return false
}
return true return true
} }
@ -107,6 +101,47 @@ func AdminView(w http.ResponseWriter, r *http.Request) {
} }
} }
func comparePasswords(hashedPwd, plainPwd string) bool {
var (
e error
)
e = bcrypt.CompareHashAndPassword(
[]byte(hashedPwd),
[]byte(plainPwd),
)
if e != nil {
return false
}
return true
}
func AdminLogout(w http.ResponseWriter, r *http.Request) {
var (
session *sessions.Session
e error
)
if !CheckAuth(w, r) {
http.Redirect(w, r, "/admin/login", 302)
return
}
session, e = Variables.CookieStore.Get(r, Variables.CookieName)
if e != nil {
log.Println("Could not get session cookie")
http.Error(w, "Error", http.StatusInternalServerError)
return
}
session.Values["authenticated"] = false
session.Values["lastLogin"] = nil
session.Save(r, w)
http.Redirect(w, r, "/admin/logout", 302)
return
}
func AdminLogin(w http.ResponseWriter, r *http.Request) { func AdminLogin(w http.ResponseWriter, r *http.Request) {
var ( var (
session *sessions.Session session *sessions.Session
@ -154,7 +189,7 @@ func AdminLogin(w http.ResponseWriter, r *http.Request) {
username = r.FormValue("username") username = r.FormValue("username")
password = r.FormValue("password") password = r.FormValue("password")
if username != Variables.AdminPassword && password != Variables.AdminPassword {
if username != Variables.AdminPassword && !comparePasswords(Variables.AdminPassword, password) {
session.AddFlash("Invalid Username or Password") session.AddFlash("Invalid Username or Password")
e = session.Save(r, w) e = session.Save(r, w)
if e != nil { if e != nil {
@ -166,7 +201,7 @@ func AdminLogin(w http.ResponseWriter, r *http.Request) {
} }
session.Values["authenticated"] = true session.Values["authenticated"] = true
session.Values["lastActive"] = time.Now().Unix()
session.Values["lastLogin"] = time.Now().Unix()
session.Save(r, w) session.Save(r, w)
http.Redirect(w, r, "/admin", 302) http.Redirect(w, r, "/admin", 302)


+ 25
- 2
Webserver/Index.go View File

@ -1,6 +1,7 @@
package Webserver package Webserver
import ( import (
"log"
"net/http" "net/http"
"PersonalWebsite/Database" "PersonalWebsite/Database"
@ -15,9 +16,31 @@ func ViewIndex(w http.ResponseWriter, r *http.Request) {
v["PageView"] = "index-intro.gohtml" v["PageView"] = "index-intro.gohtml"
v["Posts"], e = Database.GetPostsList(5, 0) v["Posts"], e = Database.GetPostsList(5, 0)
if e != nil { if e != nil {
// TODO: Handle this
http.Error(w, "Error", http.StatusInternalServerError)
log.Println(e)
http.Redirect(w, r, "/error", 302)
} }
ServeTemplate(w, r, "html/index.gohtml", v) ServeTemplate(w, r, "html/index.gohtml", v)
} }
func ViewLinks(w http.ResponseWriter, r *http.Request) {
var (
v = make(map[string]interface{})
)
v["PageView"] = "index-links.gohtml"
ServeTemplate(w, r, "html/index.gohtml", v)
}
func ViewError(w http.ResponseWriter, r *http.Request) {
var (
v = make(map[string]interface{})
)
v["PageView"] = "error.gohtml"
ServeTemplate(w, r, "html/index.gohtml", v)
}

+ 16
- 9
Webserver/Post.go View File

@ -6,6 +6,7 @@ import (
"strconv" "strconv"
"PersonalWebsite/Database" "PersonalWebsite/Database"
"PersonalWebsite/Helper"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
@ -22,9 +23,15 @@ func ViewPost(w http.ResponseWriter, r *http.Request) {
post, e = Database.GetPostById(urlParams["id"]) post, e = Database.GetPostById(urlParams["id"])
if e != nil { if e != nil {
// TODO: Forward 404
log.Println("Could not get post")
http.Error(w, "Error", http.StatusInternalServerError)
log.Println(e)
http.Redirect(w, r, "/error", 302)
return
}
post.Body, e = Helper.GetFileContents(post.HtmlPath)
if e != nil {
log.Println(e)
http.Redirect(w, r, "/error", 302)
return return
} }
@ -58,8 +65,8 @@ func ViewPostList(w http.ResponseWriter, r *http.Request, subject string) {
} else { } else {
page, e = strconv.Atoi(keys[0]) page, e = strconv.Atoi(keys[0])
if e != nil { if e != nil {
// TODO: Handle this
http.Error(w, "Error", http.StatusInternalServerError)
log.Println(e)
http.Redirect(w, r, "/error", 302)
return return
} }
} }
@ -68,15 +75,15 @@ func ViewPostList(w http.ResponseWriter, r *http.Request, subject string) {
posts, e = Database.GetPostsListBySubject(limit, offset, subject) posts, e = Database.GetPostsListBySubject(limit, offset, subject)
if e != nil { if e != nil {
// TODO: Handle this
http.Error(w, "Error", http.StatusInternalServerError)
log.Println(e)
http.Redirect(w, r, "/error", 302)
return return
} }
postsCount, e = Database.GetPostCountBySubject(subject) postsCount, e = Database.GetPostCountBySubject(subject)
if e != nil { if e != nil {
// TODO: Handle this
http.Error(w, "Error", http.StatusInternalServerError)
log.Println(e)
http.Redirect(w, r, "/error", 302)
return return
} }


+ 11
- 6
Webserver/ServeFile.go View File

@ -1,6 +1,7 @@
package Webserver package Webserver
import ( import (
"log"
"net/http" "net/http"
"path" "path"
"text/template" "text/template"
@ -18,9 +19,11 @@ var (
"html/header.gohtml", "html/header.gohtml",
"html/sidebar.gohtml", "html/sidebar.gohtml",
"html/index-intro.gohtml", "html/index-intro.gohtml",
"html/index-links.gohtml",
"html/index-post-list.gohtml", "html/index-post-list.gohtml",
"html/post-list.gohtml", "html/post-list.gohtml",
"html/post.gohtml", "html/post.gohtml",
"html/error.gohtml",
} }
) )
@ -42,8 +45,9 @@ func ServeTemplate(w http.ResponseWriter, r *http.Request, mainFile string, v ma
v["SidebarLinks"], e = Database.GetAllSidebarLinks() v["SidebarLinks"], e = Database.GetAllSidebarLinks()
if e != nil { if e != nil {
// TODO: Handle
panic(e)
log.Println(e)
http.Redirect(w, r, "/error", 302)
return
} }
files = []string{webRootJoin(mainFile)} files = []string{webRootJoin(mainFile)}
@ -64,14 +68,15 @@ func ServeTemplate(w http.ResponseWriter, r *http.Request, mainFile string, v ma
}, },
).ParseFiles(files...) ).ParseFiles(files...)
if e != nil { if e != nil {
// TODO: Handle this
panic(e)
log.Println(e)
http.Redirect(w, r, "/error", 302)
} }
w.Header().Set("Content-type", "text/html") w.Header().Set("Content-type", "text/html")
e = tpl.Execute(w, v) e = tpl.Execute(w, v)
if e != nil { if e != nil {
// TODO: Handle this
panic(e)
log.Println(e)
http.Redirect(w, r, "/error", 302)
return
} }
} }

+ 3
- 0
Webserver/Webserver.go View File

@ -58,13 +58,16 @@ func Start() error {
// Interface endpoints // Interface endpoints
r.HandleFunc("/", ViewIndex) r.HandleFunc("/", ViewIndex)
r.HandleFunc("/links", ViewLinks)
r.HandleFunc("/programming", ViewPostListProgramming) r.HandleFunc("/programming", ViewPostListProgramming)
r.HandleFunc("/pentesting", ViewPostListPentesting) r.HandleFunc("/pentesting", ViewPostListPentesting)
r.HandleFunc("/post/{id}", ViewPost) r.HandleFunc("/post/{id}", ViewPost)
r.HandleFunc("/error", ViewError)
// Administration // Administration
r.HandleFunc("/admin", AdminView) r.HandleFunc("/admin", AdminView)
r.HandleFunc("/admin/login", AdminLogin) r.HandleFunc("/admin/login", AdminLogin)
r.HandleFunc("/admin/logout", AdminLogout)
r.HandleFunc("/admin/post/new", AdminNewPost) r.HandleFunc("/admin/post/new", AdminNewPost)
r.HandleFunc("/admin/post/{id}/edit", AdminEditPost) r.HandleFunc("/admin/post/{id}/edit", AdminEditPost)


+ 3
- 1
web/css/main.css View File

@ -243,7 +243,9 @@ pre::-webkit-scrollbar-color {
} }
.post-icon { .post-icon {
max-width: 200px !important;
max-width: 50% !important;
max-height: 20em !important;
padding-bottom: 2em;
} }
.icon-div { .icon-div {


+ 3
- 0
web/html/error.gohtml View File

@ -0,0 +1,3 @@
<h2>Whoops! It looks like you've run into an error!</h2>
<p>Please click <a href="/">here</a> to go back to the home screen</p>

+ 1
- 1
web/html/header.gohtml View File

@ -7,7 +7,7 @@
<ul> <ul>
<a href="/pentesting?page=0"><li class="{{ if eq .Subject "Pentesting" }}active{{ end }}">Pentesting</li></a> <a href="/pentesting?page=0"><li class="{{ if eq .Subject "Pentesting" }}active{{ end }}">Pentesting</li></a>
<a href="/programming?page=0"><li class="{{ if eq .Subject "Programming" }}active{{ end }}">Programming</li></a> <a href="/programming?page=0"><li class="{{ if eq .Subject "Programming" }}active{{ end }}">Programming</li></a>
<a href="/links.html"><li>Links</li></a>
<a href="/links"><li>Links</li></a>
</ul> </ul>
</div> </div>
<ul class="pc-links"> <ul class="pc-links">


+ 11
- 4
web/html/index-intro.gohtml View File

@ -1,6 +1,13 @@
<h2>Tovi Jaeschke</h2> <h2>Tovi Jaeschke</h2>
<p>Hello! My name is Tovi. I'm a 21 year old programmer and computer security enthusiast.</p>
<p>My main hobbies include reading, programming, pentesting, philosophy, and designing websites. I actively develop in Go, Python, php, and HTML/CSS/JS. I enjoy using versatile, minimalist, open source programs, such as vim, st, dmenu, and dwm.</p>
<p>You can find some of my portfolio and some front-end demos <a href="https://demos.tovijaeschke.xyz">here</a></p>
<p>On this site, you will find programs I have written, CTF walkthroughs, minimalist programs I have found and begun using, and updates about my current workflow.</p>
<p>Hello! My name is Tovi. I'm 22, and I like to code.</p>
<p>I have been working as a professional software developer for about 2 years. I primarily do backend web development, and code in PHP and JS for work, but I like using GO for my personal projects.</p>
<p>I am a massive advocate for using command line utilities, and thoroughly understanding how the computer actually works, in order to have the best results when creating code.</p>
<p>On this site, I post about computer security, my linux system configuration, and general programming stuff.</p>
<p>If you want to chat, you can say hello to me <a href="mailto:tovi@tovijaeschke.xyz">here</a>, or through my linkdin <a href="https://www.linkedin.com/in/tovi-jaeschke-rogers-584755214/">here</a>. Don't be shy!</p>
{{ template "index-post-list.gohtml" . }} {{ template "index-post-list.gohtml" . }}

+ 8
- 0
web/html/index-links.gohtml View File

@ -0,0 +1,8 @@
<h2>Links</h2>
<div class="main-links">
<ul>
{{ range $link := .SidebarLinks }}
<a href="{{ $link.Link }}"><li>{{ $link.Name }}</li></a>
{{ end }}
</ul>
</div>

+ 7
- 0
web/html/index.gohtml View File

@ -1,8 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tovi Jaeschke's Homepage</title> <title>Tovi Jaeschke's Homepage</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico"/>
<link rel="stylesheet" type="text/css" href="/css/main.css"> <link rel="stylesheet" type="text/css" href="/css/main.css">
<link href='https://fonts.googleapis.com/css?family=Average|Montserrat' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Average|Montserrat' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/css/prism.css"> <link rel="stylesheet" href="/css/prism.css">
@ -21,6 +24,10 @@
{{ template "post-list.gohtml" . }} {{ template "post-list.gohtml" . }}
{{ else if eq .PageView "post.gohtml" }} {{ else if eq .PageView "post.gohtml" }}
{{ template "post.gohtml" . }} {{ template "post.gohtml" . }}
{{ else if eq .PageView "index-links.gohtml" }}
{{ template "index-links.gohtml" . }}
{{ else if eq .PageView "error.gohtml" }}
{{ template "error.gohtml" . }}
{{ end }} {{ end }}
</div> </div>
</div> </div>


+ 0
- 57
web/html/links.html View File

@ -1,57 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tovi Jaeschke's Homepage</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<link href='https://fonts.googleapis.com/css?family=Average|Montserrat' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/prism.css">
<script src="js/prism.js"></script>
<script type="text/javascript" src="js/script.js"></script>
</head>
<body>
<header>
<a href="/"><h2 href="/">Tovi Jaeschke</h2></a>
<div class="nav-toggle">
<div class="nav-toggle-bar"></div>
</div>
<div class="links">
<ul>
<a href="/pentesting.html?page=0"><li>Pentesting</li></a>
<a href="/programming.html?page=0"><li>Programming</li></a>
<a href="/personal.html"><li>Personal</li></a>
<a href="/hireme.html"><li>Hire Me</li></a>
<a href="/links.html"><li>Links</li></a>
</ul>
</div>
<ul class="pc-links">
<a href="/pentesting.html?page=0"><li>Pentesting</li></a>
<a href="/programming.html?page=0"><li>Programming</li></a>
<a href="/personal.html"><li>Personal</li></a>
<a href="/hireme.html"><li>Hire Me</li></a>
</ul>
</header>
<div class="container">
<div class="main">
<h2>Links</h2>
<div class="main-links">
<ul>
<a href="mailto:tovi@tovijaeschke.xyz"><li>Email</li></a>
<a href="https://git.tovijaeschke.xyz"><li>Git</li></a>
<a href="https://gitlab.com/tovijaeschke"><li>Gitlab</li></a>
<a href="/static/Resume.pdf"><li>Resume</li></a>
<a href="https://demos.tovijaeschke.xyz/"><li>Portfolio</li></a>
</ul>
<h2>Recent Posts</h2>
<ul>
<?php include 'php/recent-posts.php';?>
</ul>
</div>
</div>
</div>
<footer>
<a href="mailto:tovi@tovijaeschke.xyz">tovi@tovijaeschke.xyz</a>
<p>Last updated: <?php lastUpdate();?></p>
</footer>
</body>
</html>

+ 6
- 1
web/html/post.gohtml View File

@ -1,8 +1,13 @@
<h3 class='post-title'>{{ .Post.Title }}</h2> <h3 class='post-title'>{{ .Post.Title }}</h2>
{{ if .Post.MainImage }} {{ if .Post.MainImage }}
<div class='icon-div'> <div class='icon-div'>
<img class='post-icon' src='{{ .Post.MainImage }}' />
<img class='post-icon' src='/static/{{ .Post.MainImage }}' />
</div> </div>
{{ end }} {{ end }}
<div>
{{ .Post.Intro }} {{ .Post.Intro }}
</div>
<br/>
<div>
{{ .Post.Body }} {{ .Post.Body }}
</div>

BIN
web/static/1622082948272.jpg View File

Before After
Width: 3240  |  Height: 2102  |  Size: 631 KiB

BIN
web/static/favicon-16x16.png View File

Before After
Width: 16  |  Height: 16  |  Size: 183 B

BIN
web/static/favicon-32x32.png View File

Before After
Width: 32  |  Height: 32  |  Size: 310 B

BIN
web/static/favicon.ico View File

Before After

Loading…
Cancel
Save