3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 18:52:41 +01:00

Start web interface framework

This commit is contained in:
Daniel Oaks 2016-11-06 23:04:30 +10:00
parent 239a79fde2
commit 8dfa888552
6 changed files with 210 additions and 4 deletions

2
.gitignore vendored
View File

@ -97,6 +97,8 @@ _testmain.go
/_site/
/.vscode/*
/ircd*
/web-*
/web.*
/ssl.*
/tls.*
/oragono

View File

@ -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, <https://github.com/jlatt>
* Edmund Huber, maintainer of Ergonomadic, <https://github.com/edmund-huber>

68
oragono-web.go Normal file
View File

@ -0,0 +1,68 @@
// Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
// 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 <filename>] [--quiet]
oragono-web run [--conf <filename>] [--quiet]
oragono-web -h | --help
oragono-web --version
Options:
--conf <filename> 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()
}
}

17
oragono-web.yaml Normal file
View File

@ -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

77
web/config.go Normal file
View File

@ -0,0 +1,77 @@
// Copyright (c) 2012-2014 Jeremy Latt
// Copyright (c) 2014-2015 Edmund Huber
// Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
// 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
}

21
web/server.go Normal file
View File

@ -0,0 +1,21 @@
// Copyright (c) 2012-2014 Jeremy Latt
// Copyright (c) 2014-2015 Edmund Huber
// Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
// 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() {
}