diff --git a/.gitignore b/.gitignore index b4627c02..42fa04fa 100644 --- a/.gitignore +++ b/.gitignore @@ -97,6 +97,8 @@ _testmain.go /_site/ /.vscode/* /ircd* +/web-* +/web.* /ssl.* /tls.* /oragono diff --git a/README.md b/README.md index df7fec55..d5b55a76 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Also see the [mammon](https://github.com/mammon-ircd/mammon) IRC daemon for a si This project adheres to [Semantic Versioning](http://semver.org/). For the purposes of versioning, we consider the "public API" to refer to the configuration files, CLI interface and database format. +# Oragono + ## Features * UTF-8 nick and channel names with rfc7700 @@ -30,12 +32,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). For the purpo * passwords stored with [bcrypt](https://godoc.org/golang.org/x/crypto) (client account passwords also salted) * [IRCv3 support](http://ircv3.net/software/servers.html) * a heavy focus on developing with [specifications](http://oragono.io/specs.html) +* integrated REST API and web interface ## Installation ```sh -go get -go install +go build oragono.go cp oragono.yaml ircd.yaml vim ircd.yaml # modify the config file to your liking oragono initdb @@ -53,13 +55,32 @@ See the example [`oragono.yaml`](oragono.yaml). Passwords are stored using bcryp oragono genpasswd ``` -## Running the server +## Running ```sh oragono run ``` -## Credits +# Web interface + +Oragono also includes a web interface, which works with the REST API to provide a way to manage user accounts and bans. + +## Installation + +```sh +go build oragono-web.go +cp oragono-web.yaml web.yaml +vim web.yaml # modify the config file to your liking +oragono-web mkcerts +``` + +## Running + +```sh +oragono-web run +``` + +# Credits * Jeremy Latt, creator of Ergonomadic, * Edmund Huber, maintainer of Ergonomadic, diff --git a/oragono-web.go b/oragono-web.go new file mode 100644 index 00000000..74564314 --- /dev/null +++ b/oragono-web.go @@ -0,0 +1,68 @@ +// Copyright (c) 2016- Daniel Oaks +// released under the MIT license + +package main + +import ( + "fmt" + "log" + + "github.com/DanielOaks/oragono/irc" + "github.com/DanielOaks/oragono/mkcerts" + "github.com/DanielOaks/oragono/web" + "github.com/docopt/docopt-go" +) + +func main() { + version := irc.SemVer + usage := `oragono-web. +Usage: + oragono-web mkcerts [--conf ] [--quiet] + oragono-web run [--conf ] [--quiet] + oragono-web -h | --help + oragono-web --version +Options: + --conf Configuration file to use [default: web.yaml]. + --quiet Don't show startup/shutdown lines. + -h --help Show this screen. + --version Show version.` + + arguments, _ := docopt.Parse(usage, nil, true, version, false) + + configfile := arguments["--conf"].(string) + config, err := web.LoadConfig(configfile) + if err != nil { + log.Fatal("Config file did not load successfully:", err.Error()) + } + + if arguments["mkcerts"].(bool) { + if !arguments["--quiet"].(bool) { + log.Println("making self-signed certificates") + } + + for name, conf := range config.TLSListenersConf { + log.Printf(" making cert for %s listener\n", name) + host := config.Host + err := mkcerts.CreateCert("Oragono web interface", host, conf.Cert, conf.Key) + if err == nil { + if !arguments["--quiet"].(bool) { + log.Printf(" Certificate created at %s : %s\n", conf.Cert, conf.Key) + } + } else { + log.Fatal(" Could not create certificate:", err.Error()) + } + } + } else if arguments["run"].(bool) { + irc.Log.SetLevel(config.Log) + server := web.NewServer(config) + if server == nil { + log.Println("Could not load server") + return + } + if !arguments["--quiet"].(bool) { + log.Println(fmt.Sprintf("Oragono web interface v%s running", irc.SemVer)) + defer log.Println(irc.SemVer, "exiting") + } + server.Run() + } +} diff --git a/oragono-web.yaml b/oragono-web.yaml new file mode 100644 index 00000000..341069f5 --- /dev/null +++ b/oragono-web.yaml @@ -0,0 +1,17 @@ +# oragono web interface config + +# hostname of the web interface +hostname: localhost + +# address to listen on +listen: "localhost:8090" + +# tls listeners +tls-listeners: + # listener on ":6697" + ":8090": + key: web-tls.key + cert: web-tls.crt + +# log level, one of error, warn, info, debug +log: debug diff --git a/web/config.go b/web/config.go new file mode 100644 index 00000000..12bdaa9f --- /dev/null +++ b/web/config.go @@ -0,0 +1,77 @@ +// Copyright (c) 2012-2014 Jeremy Latt +// Copyright (c) 2014-2015 Edmund Huber +// Copyright (c) 2016- Daniel Oaks +// released under the MIT license + +package web + +import ( + "crypto/tls" + "errors" + "io/ioutil" + "log" + + "github.com/DanielOaks/oragono/irc" + + "gopkg.in/yaml.v2" +) + +// TLSListenConfig defines configuration options for listening on TLS +type TLSListenConfig struct { + Cert string + Key string +} + +// Certificate returns the TLS certificate assicated with this TLSListenConfig +func (conf *TLSListenConfig) Config() (*tls.Config, error) { + cert, err := tls.LoadX509KeyPair(conf.Cert, conf.Key) + if err != nil { + return nil, errors.New("tls cert+key: invalid pair") + } + + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + }, err +} + +type Config struct { + Host string + Listen string + TLSListenersConf map[string]*TLSListenConfig `yaml:"tls-listeners"` + Log string +} + +func (conf *Config) TLSListeners() map[string]*tls.Config { + tlsListeners := make(map[string]*tls.Config) + for s, tlsListenersConf := range conf.TLSListenersConf { + config, err := tlsListenersConf.Config() + if err != nil { + log.Fatal(err) + } + name, err := irc.CasefoldName(s) + if err == nil { + tlsListeners[name] = config + } else { + log.Println("Could not casefold TLS listener:", err.Error()) + } + } + return tlsListeners +} + +func LoadConfig(filename string) (config *Config, err error) { + data, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + err = yaml.Unmarshal(data, &config) + if err != nil { + return nil, err + } + + if config.Listen == "" { + return nil, errors.New("Listening address missing") + } + + return config, nil +} diff --git a/web/server.go b/web/server.go new file mode 100644 index 00000000..91b79c2d --- /dev/null +++ b/web/server.go @@ -0,0 +1,21 @@ +// Copyright (c) 2012-2014 Jeremy Latt +// Copyright (c) 2014-2015 Edmund Huber +// Copyright (c) 2016- Daniel Oaks +// released under the MIT license + +package web + +// Server is the webserver +type Server struct { +} + +// NewServer returns a new Oragono server. +func NewServer(config *Config) *Server { + server := &Server{} + + return server +} + +func (*Server) Run() { + +}