2020-03-04 11:07:12 +00:00
package main
import (
"flag"
"log"
"net/http"
"net/url"
"os"
"os/signal"
"path"
"strings"
"syscall"
)
var baseURL string = "/"
type ResponseWriterPrefix struct {
real http . ResponseWriter
prefix string
}
func ( r ResponseWriterPrefix ) Header ( ) http . Header {
return r . real . Header ( )
}
func ( r ResponseWriterPrefix ) WriteHeader ( s int ) {
if v , exists := r . real . Header ( ) [ "Location" ] ; exists && len ( v ) > 0 && ! strings . HasPrefix ( v [ 0 ] , "https://" ) && ! strings . HasPrefix ( v [ 0 ] , "http://" ) {
r . real . Header ( ) . Set ( "Location" , r . prefix + v [ 0 ] )
}
r . real . WriteHeader ( s )
}
func ( r ResponseWriterPrefix ) Write ( z [ ] byte ) ( int , error ) {
return r . real . Write ( z )
}
func StripPrefix ( prefix string , h http . Handler ) http . Handler {
if prefix == "" {
return h
}
return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
if prefix != "/" && r . URL . Path == "/" {
http . Redirect ( w , r , prefix + "/" , http . StatusFound )
} else if p := strings . TrimPrefix ( r . URL . Path , prefix ) ; len ( p ) < len ( r . URL . Path ) {
r2 := new ( http . Request )
* r2 = * r
r2 . URL = new ( url . URL )
* r2 . URL = * r . URL
r2 . URL . Path = p
h . ServeHTTP ( ResponseWriterPrefix { w , prefix } , r2 )
} else {
h . ServeHTTP ( w , r )
}
} )
}
func main ( ) {
var bind = flag . String ( "bind" , ":8081" , "Bind port/socket" )
var dsn = flag . String ( "dsn" , DSNGenerator ( ) , "DSN to connect to the MySQL server" )
2021-11-18 11:12:28 +00:00
var dummyauth = flag . Bool ( "dummy-auth" , false , "If set, allow any authentication credentials" )
2023-03-07 01:53:47 +00:00
flag . StringVar ( & mainBanner , "banner-message" , mainBanner , "Display a message to connected user, at the top of the screen" )
2021-10-01 16:28:53 +00:00
flag . StringVar ( & DevProxy , "dev" , DevProxy , "Proxify traffic to this host for static assets" )
2020-03-04 11:07:12 +00:00
flag . StringVar ( & baseURL , "baseurl" , baseURL , "URL prepended to each URL" )
2021-03-01 16:47:00 +00:00
flag . UintVar ( & currentPromo , "current-promo" , currentPromo , "Year of the current promotion" )
2022-03-01 15:38:52 +00:00
flag . UintVar ( & OffsetQuestionTimer , "offset-question-timer" , OffsetQuestionTimer , "Duration to wait before sending pause msg in direct mode (in milliseconds)" )
2022-09-07 12:08:23 +00:00
flag . BoolVar ( & allowLocalAuth , "allow-local-auth" , false , "Allow local authentication for all users (bypass OIDC)." )
2021-09-22 15:02:30 +00:00
flag . Var ( & localAuthUsers , "local-auth-user" , "Allow local authentication for this user (bypass OIDC)." )
2020-03-04 11:07:12 +00:00
flag . Parse ( )
// Sanitize options
var err error
log . Println ( "Checking paths..." )
if err = sanitizeStaticOptions ( ) ; err != nil {
log . Fatal ( err )
}
if baseURL != "/" {
baseURL = path . Clean ( baseURL )
} else {
baseURL = ""
}
2021-11-18 11:12:28 +00:00
if dummyauth != nil && * dummyauth == true {
LocalAuthFunc = dummyAuth
}
2020-03-04 11:07:12 +00:00
// Initialize contents
log . Println ( "Opening database..." )
if err := DBInit ( * dsn ) ; err != nil {
log . Fatal ( "Cannot open the database: " , err )
}
defer DBClose ( )
log . Println ( "Creating database..." )
if err := DBCreate ( ) ; err != nil {
log . Fatal ( "Cannot create database: " , err )
}
2022-07-09 17:42:00 +00:00
a := NewApp ( )
go a . Start ( * bind )
initializeOIDC ( a . router )
2022-09-05 01:29:47 +00:00
initializeDroneOauth ( )
2022-07-09 17:42:00 +00:00
2020-03-04 11:07:12 +00:00
// Prepare graceful shutdown
interrupt := make ( chan os . Signal , 1 )
signal . Notify ( interrupt , os . Interrupt , syscall . SIGTERM )
// Wait shutdown signal
<- interrupt
log . Print ( "The service is shutting down..." )
2022-07-09 17:42:00 +00:00
a . Stop ( )
2022-09-04 14:36:15 +00:00
if gitlabToken != nil {
2022-09-04 22:54:33 +00:00
saveOAuth2Token ( OAUTH_GITLAB_FILE , gitlabToken ( ) )
2022-09-04 14:36:15 +00:00
}
2020-03-04 11:07:12 +00:00
log . Println ( "done" )
}