func main() { var help bool var bindto, config_file string var config_contents []byte var application_tmpl, memberlist_tmpl, print_tmpl *template.Template var unique_member_detail_template *template.Template var authenticator *ancientauth.Authenticator var debug_authenticator bool var config membersys.MembersysConfig var db *membersys.MembershipDB var err error flag.BoolVar(&help, "help", false, "Display help") flag.StringVar(&bindto, "bind", "127.0.0.1:8080", "The address to bind the web server to") flag.StringVar(&config_file, "config", "", "Path to a file containing a MembersysConfig protocol buffer") flag.BoolVar(&debug_authenticator, "debug-authenticator", false, "Debug the authenticator?") flag.Parse() if help || config_file == "" { flag.Usage() os.Exit(1) } config_contents, err = ioutil.ReadFile(config_file) if err != nil { log.Fatal("Unable to read ", config_file, ": ", err) } err = proto.Unmarshal(config_contents, &config) if err != nil { err = proto.UnmarshalText(string(config_contents), &config) } if err != nil { log.Fatal("Error parsing ", config_file, ": ", err) } // Load and parse the HTML templates to be displayed. application_tmpl, err = template.ParseFiles( config.GetTemplateDir() + "/form.html") if err != nil { log.Fatal("Unable to parse form template: ", err) } print_tmpl, err = template.ParseFiles( config.GetTemplateDir() + "/printlayout.html") if err != nil { log.Fatal("Unable to parse print layout template: ", err) } memberlist_tmpl = template.New("memberlist") memberlist_tmpl.Funcs(fmap) memberlist_tmpl, err = memberlist_tmpl.ParseFiles( config.GetTemplateDir() + "/memberlist.html") if err != nil { log.Fatal("Unable to parse member list template: ", err) } unique_member_detail_template = template.New("memberdetail") unique_member_detail_template.Funcs(fmap) unique_member_detail_template, err = unique_member_detail_template.ParseFiles( config.GetTemplateDir() + "/memberdetail.html") if err != nil { log.Fatal("Unable to parse member detail template: ", err) } authenticator, err = ancientauth.NewAuthenticator( config.AuthenticationConfig.GetAppName(), config.AuthenticationConfig.GetCertPath(), config.AuthenticationConfig.GetKeyPath(), config.AuthenticationConfig.GetCaBundlePath(), config.AuthenticationConfig.GetAuthServerHost(), config.AuthenticationConfig.GetX509KeyserverHost(), int(config.AuthenticationConfig.GetX509CertificateCacheSize())) if err != nil { log.Fatal("Unable to assemble authenticator: ", err) } if debug_authenticator { authenticator.Debug() } db, err = membersys.NewMembershipDB( config.DatabaseConfig.GetDatabaseServer(), config.DatabaseConfig.GetDatabaseName(), time.Duration(config.DatabaseConfig.GetDatabaseTimeout())*time.Millisecond) if err != nil { log.Fatal("Unable to connect to the cassandra DB ", config.DatabaseConfig.GetDatabaseServer(), " at ", config.DatabaseConfig.GetDatabaseName(), ": ", err) } // Register the URL handlers to be invoked. http.Handle("/admin/api/members", &MemberListHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, pagesize: config.GetResultPageSize(), }) http.Handle("/admin/api/applicants", &ApplicantListHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, pagesize: config.GetResultPageSize(), }) http.Handle("/admin/api/queue", &MemberQueueListHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, pagesize: config.GetResultPageSize(), }) http.Handle("/admin/api/dequeue", &MemberDeQueueListHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, pagesize: config.GetResultPageSize(), }) http.Handle("/admin/api/trash", &MemberTrashListHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, pagesize: config.GetResultPageSize(), }) http.Handle("/admin/api/accept", &MemberAcceptHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin/api/reject", &MemberRejectHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin/api/editfee", &MemberFeeHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin/api/agreement-upload", &MemberAgreementUploadHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin/api/cancel-queued", &MemberQueueCancelHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin/api/goodbye-member", &MemberGoodbyeHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin/api/member", &MemberDetailHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, }) http.Handle("/admin", &TotalListHandler{ admingroup: config.AuthenticationConfig.GetAuthGroup(), auth: authenticator, database: db, pagesize: config.GetResultPageSize(), template: memberlist_tmpl, uniqueMemberTemplate: unique_member_detail_template, }) http.HandleFunc("/barcode", MakeBarcode) http.Handle("/", &FormInputHandler{ applicationTmpl: application_tmpl, database: db, passthrough: http.FileServer(http.Dir(config.GetTemplateDir())), printTmpl: print_tmpl, useProxyRealIP: config.GetUseProxyRealIp(), }) err = http.ListenAndServe(bindto, nil) if err != nil { log.Fatal("ListenAndServe: ", err) } }
func main() { var help bool var bindto, template_dir string var lockserv, lockboot, servicename string var ca, pub, priv, authserver string var requested_scope string var dbserver, keyspace string var searchif_tmpl *template.Template var permission_denied_tmpl *template.Template var exporter *exportedservice.ServiceExporter var authenticator *ancientauth.Authenticator var client *cassandra.RetryCassandraClient var ire *cassandra.InvalidRequestException var err error flag.BoolVar(&help, "help", false, "Display help") flag.StringVar(&bindto, "bind", "[::1]:8080", "The address to bind the web server to") flag.StringVar(&lockserv, "lockserver-uri", os.Getenv("DOOZER_URI"), "URI of a Doozer cluster to connect to") flag.StringVar(&ca, "cacert", "cacert.pem", "Path to the X.509 certificate of the certificate authority") flag.StringVar(&pub, "cert", "starstock.pem", "Path to the X.509 certificate") flag.StringVar(&priv, "key", "starstock.key", "Path to the X.509 private key file") flag.StringVar(&authserver, "auth-server", "login.ancient-solutions.com", "The server to send the user to") flag.StringVar(&template_dir, "template-dir", "", "Path to the directory with the HTML templates") flag.StringVar(&lockboot, "lockserver-boot-uri", os.Getenv("DOOZER_BOOT_URI"), "Boot URI to resolve the Doozer cluster name (if required)") flag.StringVar(&servicename, "service-name", "", "Service name to publish as to the lock server") flag.StringVar(&requested_scope, "scope", "staff", "People need to be in this scope to use the application") flag.StringVar(&dbserver, "cassandra-server", "localhost:9160", "Cassandra database server to use") flag.StringVar(&keyspace, "keyspace", "starstock", "Cassandra keyspace to use for accessing stock data") flag.Parse() if help { flag.Usage() os.Exit(1) } if len(template_dir) <= 0 { log.Fatal("The --template-dir flag must not be empty") } // Load and parse the HTML templates to be displayed. searchif_tmpl, err = template.ParseFiles(template_dir + "/search.tmpl") if err != nil { log.Fatal("Unable to parse search template: ", err) } // Load and parse the HTML templates to be displayed. permission_denied_tmpl, err = template.ParseFiles(template_dir + "/permission_denied.tmpl") if err != nil { log.Fatal("Unable to parse form template: ", err) } // Create the AncientAuth client authenticator, err = ancientauth.NewAuthenticator("StarStock", pub, priv, ca, authserver) if err != nil { log.Fatal("NewAuthenticator: ", err) } // Connect to the Cassandra server. client, err = cassandra.NewRetryCassandraClientTimeout(dbserver, 10*time.Second) if err != nil { log.Fatal("Error opening connection to ", dbserver, ": ", err) } ire, err = client.SetKeyspace(keyspace) if ire != nil { log.Fatal("Error setting keyspace to ", keyspace, ": ", ire.Why) } if err != nil { log.Fatal("Error setting keyspace to ", keyspace, ": ", err) } // Register the URL handler to be invoked. http.Handle("/css/", http.FileServer(http.Dir(template_dir))) http.Handle("/js/", http.FileServer(http.Dir(template_dir))) http.Handle("/api/product", &ProductViewAPI{ authenticator: authenticator, client: client, scope: requested_scope, }) http.Handle("/api/edit-product", &ProductEditAPI{ authenticator: authenticator, client: client, scope: requested_scope, }) http.Handle("/api/products", &ProductSearchAPI{ authenticator: authenticator, client: client, scope: requested_scope, }) http.Handle("/", &ProductSearchForm{ authenticator: authenticator, scope: requested_scope, searchifTmpl: searchif_tmpl, permissionDeniedTmpl: permission_denied_tmpl, }) // If a lock server was specified, attempt to use an anonymous port as // a Doozer exported HTTP service. Otherwise, just bind to the address // given in bindto, for debugging etc. if len(lockserv) > 0 { exporter, err = exportedservice.NewExporter(lockserv, lockboot) if err != nil { log.Fatal("doozer.DialUri ", lockserv, " (", lockboot, "): ", err) } defer exporter.UnexportPort() err = exporter.ListenAndServeNamedHTTP(servicename, bindto, nil) if err != nil { log.Fatal("ListenAndServe: ", err) } } else { err = http.ListenAndServe(bindto, nil) if err != nil { log.Fatal("ListenAndServe: ", err) } } }