2017-12-04 00:26:09 +00:00
package main
import (
2017-12-04 03:30:38 +00:00
"archive/zip"
"context"
2017-12-04 00:26:09 +00:00
"database/sql"
"fmt"
2017-12-04 03:30:38 +00:00
_ "github.com/mattn/go-sqlite3"
2017-12-05 01:39:33 +00:00
"golang.org/x/crypto/bcrypt"
2017-12-04 00:26:09 +00:00
"io"
2017-12-07 18:36:52 +00:00
"math/rand"
2017-12-04 00:26:09 +00:00
"net/http"
"os"
2017-12-04 03:30:38 +00:00
"path/filepath"
2017-12-04 00:26:09 +00:00
2017-12-04 03:30:38 +00:00
"github.com/google/go-github/github"
2017-12-04 00:26:09 +00:00
)
2017-12-07 18:36:52 +00:00
func RandomString ( n int ) string {
var letter = [ ] rune ( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-={}[]" )
b := make ( [ ] rune , n )
for i := range b {
b [ i ] = letter [ rand . Intn ( len ( letter ) ) ]
}
return string ( b )
}
2017-12-04 03:30:38 +00:00
func Setup ( ) {
defer LockFile ( )
// Create users SQLite3 file
2017-12-04 00:26:09 +00:00
fmt . Println ( "Initializing the database" )
2017-12-04 03:30:38 +00:00
2017-12-04 00:26:09 +00:00
os . MkdirAll ( "assets/config/" , 0755 )
2017-12-04 03:31:42 +00:00
os . Mkdir ( "podcasts" , 0755 )
2017-12-04 03:30:38 +00:00
os . Create ( "assets/config/users.db" )
db , err := sql . Open ( "sqlite3" , "assets/config/users.db" )
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem opening database file! %v" , err )
2017-12-04 03:30:38 +00:00
}
_ , err = db . Exec ( "CREATE TABLE IF NOT EXISTS `users` ( `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, `username` TEXT UNIQUE, `hash` TEXT, `realname` TEXT, `email` TEXT, `permissions` INTEGER )" )
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem creating database! %v" , err )
2017-12-04 03:30:38 +00:00
}
2017-12-05 01:39:33 +00:00
2017-12-07 18:36:52 +00:00
text := RandomString ( 14 )
fmt . Println ( "Admin password: " , text )
2017-12-05 18:52:22 +00:00
hash , err := bcrypt . GenerateFromPassword ( [ ] byte ( text ) , 4 )
2017-12-07 18:36:52 +00:00
if err != nil {
fmt . Println ( "Error generating hash" , err )
}
2017-12-05 18:52:22 +00:00
if bcrypt . CompareHashAndPassword ( hash , [ ] byte ( text ) ) == nil {
fmt . Println ( "Password hashed" )
}
2017-12-07 18:36:52 +00:00
_ , err = db . Exec ( "INSERT INTO users(id,username,hash,realname,email,permissions) VALUES (0,'admin','" + string ( hash ) + "','Administrator','admin@localhost',2)" )
2017-12-05 18:52:22 +00:00
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem creating database! %v" , err )
2017-12-05 18:52:22 +00:00
}
defer db . Close ( )
2017-12-04 03:30:38 +00:00
// Download web assets
fmt . Println ( "Downloading web assets" )
os . MkdirAll ( "assets/web/" , 0755 )
client := github . NewClient ( nil ) . Repositories
ctx := context . Background ( )
res , _ , err := client . GetLatestRelease ( ctx , "gmemstr" , "pogo" )
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem creating database! %v" , err )
2017-12-04 03:30:38 +00:00
}
for i := 0 ; i < len ( res . Assets ) ; i ++ {
if res . Assets [ i ] . GetName ( ) == "webassets.zip" {
download := res . Assets [ i ]
2017-12-07 18:36:52 +00:00
fmt . Println ( "Release found: %v" , download . GetBrowserDownloadURL ( ) )
2017-12-04 03:30:38 +00:00
tmpfile , err := os . Create ( download . GetName ( ) )
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem creating webassets file! %v" , err )
2017-12-04 03:30:38 +00:00
}
var j io . Reader = ( * os . File ) ( tmpfile )
defer tmpfile . Close ( )
j , s , err := client . DownloadReleaseAsset ( ctx , "gmemstr" , "pogo" , download . GetID ( ) )
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem downloading webassets! %v" , err )
2017-12-04 03:30:38 +00:00
}
if j == nil {
resp , err := http . Get ( s )
defer resp . Body . Close ( )
_ , err = io . Copy ( tmpfile , resp . Body )
if err != nil {
2017-12-07 18:36:52 +00:00
fmt . Println ( "Problem creating webassets file! %v" , err )
2017-12-04 03:30:38 +00:00
}
fmt . Println ( "Download complete\nUnzipping" )
err = Unzip ( download . GetName ( ) , "assets/web" )
defer os . Remove ( download . GetName ( ) ) // Remove zip
} else {
fmt . Println ( "Unexpected error, please open an issue!" )
}
}
}
}
func LockFile ( ) {
2017-12-05 01:39:33 +00:00
lock , err := os . Create ( ".lock" )
2017-12-04 03:30:38 +00:00
if err != nil {
fmt . Println ( "Error: %v" , err )
}
2017-12-05 01:39:33 +00:00
lock . Write ( [ ] byte ( "This file left intentionally empty" ) )
2017-12-04 03:30:38 +00:00
defer lock . Close ( )
2017-12-04 00:26:09 +00:00
}
2017-12-04 03:30:38 +00:00
// From https://stackoverflow.com/questions/20357223/easy-way-to-unzip-file-with-golang
func Unzip ( src , dest string ) error {
r , err := zip . OpenReader ( src )
if err != nil {
return err
}
defer func ( ) {
if err := r . Close ( ) ; err != nil {
panic ( err )
}
} ( )
os . MkdirAll ( dest , 0755 )
// Closure to address file descriptors issue with all the deferred .Close() methods
extractAndWriteFile := func ( f * zip . File ) error {
rc , err := f . Open ( )
if err != nil {
return err
}
defer func ( ) {
if err := rc . Close ( ) ; err != nil {
panic ( err )
}
} ( )
path := filepath . Join ( dest , f . Name )
if f . FileInfo ( ) . IsDir ( ) {
os . MkdirAll ( path , f . Mode ( ) )
} else {
os . MkdirAll ( filepath . Dir ( path ) , f . Mode ( ) )
f , err := os . OpenFile ( path , os . O_WRONLY | os . O_CREATE | os . O_TRUNC , f . Mode ( ) )
if err != nil {
return err
}
defer func ( ) {
if err := f . Close ( ) ; err != nil {
panic ( err )
}
} ( )
_ , err = io . Copy ( f , rc )
if err != nil {
return err
}
}
return nil
}
for _ , f := range r . File {
err := extractAndWriteFile ( f )
if err != nil {
return err
}
}
2017-12-04 00:26:09 +00:00
2017-12-04 03:30:38 +00:00
return nil
2017-12-04 00:26:09 +00:00
}