restapi: Initial commit

This commit is contained in:
Daniel Oaks 2016-11-06 11:05:29 +10:00
parent 4402e3e3aa
commit ee3853f845
6 changed files with 110 additions and 0 deletions

@ -43,6 +43,10 @@ func NewClientLookupSet() *ClientLookupSet {
}
}
func (clients *ClientLookupSet) Count() int {
return len(clients.ByNick)
}
func (clients *ClientLookupSet) Has(nick string) bool {
casefoldedName, err := CasefoldName(nick)
if err == nil {

@ -89,6 +89,11 @@ func (conf *OperConfig) PasswordBytes() []byte {
return bytes
}
type RestAPIConfig struct {
Enabled bool
Listen string
}
type ConnectionLimitsConfig struct {
CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
@ -108,6 +113,7 @@ type Config struct {
Listen []string
Wslisten string `yaml:"ws-listen"`
TLSListeners map[string]*TLSListenConfig `yaml:"tls-listeners"`
RestAPI RestAPIConfig `yaml:"rest-api"`
CheckIdent bool `yaml:"check-ident"`
Log string
MOTD string

@ -80,6 +80,20 @@ func NewDLineManager() *DLineManager {
return &dm
}
// AllBans returns all bans (for use with APIs, etc).
func (dm *DLineManager) AllBans() map[string]IPBanInfo {
allb := make(map[string]IPBanInfo)
for name, info := range dm.addresses {
allb[name] = info.Info
}
for name, info := range dm.networks {
allb[name] = info.Info
}
return allb
}
// AddNetwork adds a network to the blocked list.
func (dm *DLineManager) AddNetwork(network net.IPNet, length *IPRestrictTime, reason string, operReason string) {
netString := network.String()

70
irc/rest_api.go Normal file

@ -0,0 +1,70 @@
// Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
// released under the MIT license
// viewing and modifying accounts, registered channels, dlines, rehashing, etc
package irc
import (
"encoding/json"
"net/http"
"fmt"
"github.com/gorilla/mux"
)
const restErr = "{\"error\":\"An unknown error occurred\"}"
// restAPIServer 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 restAPIServer *Server
type restStatusResp struct {
Clients int `json:"clients"`
Opers int `json:"opers"`
Channels int `json:"channels"`
}
type restDLinesResp struct {
DLines map[string]IPBanInfo `json:"dlines"`
}
func restStatus(w http.ResponseWriter, r *http.Request) {
rs := restStatusResp{
Clients: restAPIServer.clients.Count(),
Opers: len(restAPIServer.operators),
Channels: len(restAPIServer.channels),
}
b, err := json.Marshal(rs)
if err != nil {
fmt.Fprintln(w, restErr)
} else {
fmt.Fprintln(w, string(b))
}
}
func restDLines(w http.ResponseWriter, r *http.Request) {
rs := restDLinesResp{
DLines: restAPIServer.dlines.AllBans(),
}
b, err := json.Marshal(rs)
if err != nil {
fmt.Fprintln(w, restErr)
} else {
fmt.Fprintln(w, string(b))
}
}
func (s *Server) startRestAPI() {
// so handlers can ref it later
restAPIServer = s
// start router
r := mux.NewRouter()
r.HandleFunc("/status", restStatus)
r.HandleFunc("/dlines", restDLines)
// start api
go http.ListenAndServe(s.restAPI.Listen, r)
}

@ -100,6 +100,7 @@ type Server struct {
passwords *PasswordManager
rehashMutex sync.Mutex
rehashSignal chan os.Signal
restAPI *RestAPIConfig
signals chan os.Signal
store buntdb.DB
whoWas *WhoWasList
@ -183,6 +184,7 @@ func NewServer(configFilename string, config *Config) *Server {
operators: opers,
signals: make(chan os.Signal, len(ServerExitSignals)),
rehashSignal: make(chan os.Signal, 1),
restAPI: &config.Server.RestAPI,
whoWas: NewWhoWasList(config.Limits.WhowasEntries),
checkIdent: config.Server.CheckIdent,
}
@ -260,6 +262,12 @@ func NewServer(configFilename string, config *Config) *Server {
server.setISupport()
// start API if enabled
if server.restAPI.Enabled {
Log.info.Printf("%s rest API started on %s .", server.name, server.restAPI.Listen)
server.startRestAPI()
}
return server
}

@ -27,6 +27,14 @@ server:
key: tls.key
cert: tls.crt
# rest API, for use with web interface
rest-api:
# whether the API is enabled or not
enabled: true
# rest API listening port
listen: "localhost:8090"
# use ident protocol to get usernames
check-ident: true