From f7f049973f2cfd9a1a3caa9fa5f6edaf78fa0745 Mon Sep 17 00:00:00 2001 From: Daniel Oaks Date: Thu, 5 Oct 2017 17:14:16 +1000 Subject: [PATCH] Rip out REST API and web interface. It's not really used and I'd rather not have it here unless I'm able to actively maintain it properly and build out the web interface. I might re-add it later but for now I'd rather not have it unless anyone's actively using it. --- README.md | 24 +----- docs/INFO.md | 15 ---- irc/config.go | 9 +-- irc/rest_api.go | 200 ----------------------------------------------- irc/server.go | 39 --------- oragono-web.yaml | 17 ---- oragono.yaml | 8 -- web/config.go | 70 ----------------- web/server.go | 21 ----- 9 files changed, 2 insertions(+), 401 deletions(-) delete mode 100644 irc/rest_api.go delete mode 100644 oragono-web.yaml delete mode 100644 web/config.go delete mode 100644 web/server.go diff --git a/README.md b/README.md index 3218706f..906ae536 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). For the purpo ## Features -* UTF-8 nick and channel names with rfc7613 +* UTF-8 nick and channel names with rfc7613 (PRECIS) * [yaml](http://yaml.org/) configuration * native TLS/SSL support * server password (`PASS` command) @@ -32,7 +32,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). For the purpo * banning ips/nets and masks with `KLINE` and `DLINE` * [IRCv3 support](http://ircv3.net/software/servers.html) * a heavy focus on developing with [specifications](http://oragono.io/specs.html) -* integrated (alpha) REST API and web interface ## Installation @@ -131,27 +130,6 @@ After this, your channel will remember the fact that you're the owner, the topic Make sure to setup [SASL](https://freenode.net/kb/answer/sasl) in your client to automatically login to your account when you next join the server. - - # Credits * Jeremy Latt, creator of Ergonomadic, diff --git a/docs/INFO.md b/docs/INFO.md index 56b3e2eb..8560431a 100644 --- a/docs/INFO.md +++ b/docs/INFO.md @@ -72,21 +72,6 @@ This will make the server rehash its configuration files and TLS certificates, a useful if you're automatically updating your TLS certs! -## REST API - -Oragono contains a draft, very early REST API implementation. My plans for this is to allow -external web interfaces or other automated programs to monitor what's going on with the -server, apply/remove bans, and to essentially allow administration of the server without -being connected to it and opered-up. This sort of API mimics InspIRCd and Anope, which -contain similar APIs. - -I'm not sure exactly how it's going to continue to be developed, and I'm sure there'll be -lots of changes around appropriately restricting access to the API, which is why it's -disabled for now and not exposed in our Docker builds. As well, while it's very unstable, -the REST API doesn't count for our SemVer versioning. When this feature is more developed -and I'm happy with where it's at, I'll provide proper support and documentation for the API. - - ## Rejected Features 'Rejected' sounds harsh, but basically these are features I've decided I'm not gonna diff --git a/irc/config.go b/irc/config.go index 24f2d324..22dcfdf0 100644 --- a/irc/config.go +++ b/irc/config.go @@ -108,12 +108,6 @@ func (conf *OperConfig) PasswordBytes() []byte { return bytes } -// RestAPIConfig controls the integrated REST API. -type RestAPIConfig struct { - Enabled bool - Listen string -} - // ConnectionLimitsConfig controls the automated connection limits. type ConnectionLimitsConfig struct { Enabled bool @@ -198,8 +192,7 @@ type Config struct { Listen []string TLSListeners map[string]*TLSListenConfig `yaml:"tls-listeners"` STS STSConfig - RestAPI RestAPIConfig `yaml:"rest-api"` - CheckIdent bool `yaml:"check-ident"` + CheckIdent bool `yaml:"check-ident"` MOTD string ProxyAllowedFrom []string `yaml:"proxy-allowed-from"` MaxSendQString string `yaml:"max-sendq"` diff --git a/irc/rest_api.go b/irc/rest_api.go deleted file mode 100644 index 817406ed..00000000 --- a/irc/rest_api.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) 2016-2017 Daniel Oaks -// released under the MIT license - -// viewing and modifying accounts, registered channels, dlines, rehashing, etc - -package irc - -import ( - "encoding/json" - "net/http" - "strconv" - "time" - - "fmt" - - "github.com/gorilla/mux" - "github.com/tidwall/buntdb" -) - -const restErr = "{\"error\":\"An unknown error occurred\"}" - -// ircServer is used to keep a link to the current running server since this is the best -// way to do it, given how HTTP handlers dispatch and work. -var ircServer *Server - -type restInfoResp struct { - ServerName string `json:"server-name"` - NetworkName string `json:"network-name"` - - Version string `json:"version"` -} - -type restStatusResp struct { - Clients int `json:"clients"` - Opers int `json:"opers"` - Channels int `json:"channels"` -} - -type restXLinesResp struct { - DLines map[string]IPBanInfo `json:"dlines"` - KLines map[string]IPBanInfo `json:"klines"` -} - -type restAcct struct { - Name string `json:"name"` - RegisteredAt time.Time `json:"registered-at"` - Clients int `json:"clients"` -} - -type restAccountsResp struct { - Verified map[string]restAcct `json:"verified"` -} - -type restRehashResp struct { - Successful bool `json:"successful"` - Error string `json:"error"` - Time time.Time `json:"time"` -} - -func restInfo(w http.ResponseWriter, r *http.Request) { - rs := restInfoResp{ - Version: SemVer, - ServerName: ircServer.name, - NetworkName: ircServer.networkName, - } - b, err := json.Marshal(rs) - if err != nil { - fmt.Fprintln(w, restErr) - } else { - fmt.Fprintln(w, string(b)) - } -} - -func restStatus(w http.ResponseWriter, r *http.Request) { - rs := restStatusResp{ - Clients: ircServer.clients.Count(), - Opers: len(ircServer.operators), - Channels: ircServer.channels.Len(), - } - b, err := json.Marshal(rs) - if err != nil { - fmt.Fprintln(w, restErr) - } else { - fmt.Fprintln(w, string(b)) - } -} - -func restGetXLines(w http.ResponseWriter, r *http.Request) { - rs := restXLinesResp{ - DLines: ircServer.dlines.AllBans(), - KLines: ircServer.klines.AllBans(), - } - b, err := json.Marshal(rs) - if err != nil { - fmt.Fprintln(w, restErr) - } else { - fmt.Fprintln(w, string(b)) - } -} - -func restGetAccounts(w http.ResponseWriter, r *http.Request) { - rs := restAccountsResp{ - Verified: make(map[string]restAcct), - } - - // get accounts - err := ircServer.store.View(func(tx *buntdb.Tx) error { - tx.AscendKeys("account.exists *", func(key, value string) bool { - key = key[len("account.exists "):] - _, err := tx.Get(fmt.Sprintf(keyAccountVerified, key)) - verified := err == nil - fmt.Println(fmt.Sprintf(keyAccountVerified, key)) - - // get other details - name, _ := tx.Get(fmt.Sprintf(keyAccountName, key)) - regTimeStr, _ := tx.Get(fmt.Sprintf(keyAccountRegTime, key)) - regTimeInt, _ := strconv.ParseInt(regTimeStr, 10, 64) - regTime := time.Unix(regTimeInt, 0) - - var clients int - acct := ircServer.accounts[key] - if acct != nil { - clients = len(acct.Clients) - } - - if verified { - rs.Verified[key] = restAcct{ - Name: name, - RegisteredAt: regTime, - Clients: clients, - } - } else { - //TODO(dan): Add to unverified list - } - - return true // true to continue I guess? - }) - - return nil - }) - - b, err := json.Marshal(rs) - if err != nil { - fmt.Fprintln(w, restErr) - } else { - fmt.Fprintln(w, string(b)) - } -} - -func restRehash(w http.ResponseWriter, r *http.Request) { - err := ircServer.rehash() - - rs := restRehashResp{ - Successful: err == nil, - Time: time.Now(), - } - if err != nil { - rs.Error = err.Error() - } - - b, err := json.Marshal(rs) - if err != nil { - fmt.Fprintln(w, restErr) - } else { - fmt.Fprintln(w, string(b)) - } -} - -func StartRestAPI(s *Server, listenAddr string) (*http.Server, error) { - // so handlers can ref it later - ircServer = s - - // start router - r := mux.NewRouter() - - // GET methods - rg := r.Methods("GET").Subrouter() - rg.HandleFunc("/info", restInfo) - rg.HandleFunc("/status", restStatus) - rg.HandleFunc("/xlines", restGetXLines) - rg.HandleFunc("/accounts", restGetAccounts) - - // PUT methods - rp := r.Methods("POST").Subrouter() - rp.HandleFunc("/rehash", restRehash) - - // start api - httpserver := http.Server{ - Addr: listenAddr, - Handler: r, - } - - go func() { - if err := httpserver.ListenAndServe(); err != nil { - s.logger.Error("listeners", fmt.Sprintf("Rest API listenAndServe error: %s", err)) - } - }() - - return &httpserver, nil -} diff --git a/irc/server.go b/irc/server.go index 555afcc0..8e411b1a 100644 --- a/irc/server.go +++ b/irc/server.go @@ -7,14 +7,12 @@ package irc import ( "bufio" - "context" "crypto/tls" "encoding/base64" "fmt" "log" "math/rand" "net" - "net/http" "os" "os/signal" "strconv" @@ -39,14 +37,6 @@ var ( couldNotParseIPMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "Unable to parse your IP address")}[0]).Line() ) -const ( - // when shutting down the REST server, wait this long - // before killing active connections. TODO: this might not be - // necessary at all? but it seems prudent to avoid potential resource - // leaks - httpShutdownTimeout = time.Second -) - // Limits holds the maximum limits for various things such as topic lengths. type Limits struct { AwayLen int @@ -116,8 +106,6 @@ type Server struct { registeredChannelsMutex sync.RWMutex rehashMutex sync.Mutex rehashSignal chan os.Signal - restAPI RestAPIConfig - restAPIServer *http.Server proxyAllowedFrom []string signals chan os.Signal snomasks *SnoManager @@ -1445,7 +1433,6 @@ func (server *Server) applyConfig(config *Config, initial bool) error { // we are now open for business server.setupListeners(config) - server.setupRestAPI(config) return nil } @@ -1583,32 +1570,6 @@ func (server *Server) setupListeners(config *Config) { } } -func (server *Server) setupRestAPI(config *Config) { - restAPIEnabled := config.Server.RestAPI.Enabled - restAPIStarted := server.restAPIServer != nil - restAPIListenAddrChanged := server.restAPI.Listen != config.Server.RestAPI.Listen - - // stop an existing REST server if it's been disabled or the addr changed - if restAPIStarted && (!restAPIEnabled || restAPIListenAddrChanged) { - ctx, _ := context.WithTimeout(context.Background(), httpShutdownTimeout) - server.restAPIServer.Shutdown(ctx) - server.restAPIServer.Close() - server.logger.Info("rehash", "server", fmt.Sprintf("%s rest API stopped on %s.", server.name, server.restAPI.Listen)) - server.restAPIServer = nil - } - - // start a new one if it's enabled or the addr changed - if restAPIEnabled && (!restAPIStarted || restAPIListenAddrChanged) { - server.restAPIServer, _ = StartRestAPI(server, config.Server.RestAPI.Listen) - server.logger.Info( - "rehash", "server", - fmt.Sprintf("%s rest API started on %s.", server.name, config.Server.RestAPI.Listen)) - } - - // save the config information - server.restAPI = config.Server.RestAPI -} - func (server *Server) GetDefaultChannelModes() Modes { server.configurableStateMutex.RLock() defer server.configurableStateMutex.RUnlock() diff --git a/oragono-web.yaml b/oragono-web.yaml deleted file mode 100644 index 341069f5..00000000 --- a/oragono-web.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# 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/oragono.yaml b/oragono.yaml index e601954c..b759cece 100644 --- a/oragono.yaml +++ b/oragono.yaml @@ -43,14 +43,6 @@ server: # should clients include this STS policy when they ship their inbuilt preload lists? preload: false - # rest management API, for use with web interface - rest-api: - # whether the API is enabled or not - enabled: false - - # rest API listening port - listen: "localhost:8090" - # use ident protocol to get usernames check-ident: true diff --git a/web/config.go b/web/config.go deleted file mode 100644 index fa68e03e..00000000 --- a/web/config.go +++ /dev/null @@ -1,70 +0,0 @@ -// 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" - - "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) - } - tlsListeners[name] = config - } - 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 deleted file mode 100644 index 66573aaa..00000000 --- a/web/server.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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() { - -}