shodan

package module
v0.0.0-...-e6a6799 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2021 License: AGPL-3.0 Imports: 19 Imported by: 0

README

Deprecation Notice: His repository is for historical purposes only.

SHODAN

A modular bot for Discord.

Building SHODAN

Requirements
  • Go 1.7, tested with 1.7.4 specifically
  • Godep (for development)

Development

After commiting a feature, make sure to run go run build.go to regenerate the configuration.

Running SHODAN

These are the environment variables currently available in core builds.

Core
  • DISCORD_TOKEN Authentication token for the bot account
  • WEB_ADDR HTTP listener bind address
  • REDIS_URL Redis URL
  • POSTGRES_URL Postgres URL
  • M_MODULENAME Load MODULENAME.
mod_oauth
  • OAUTH_CLIENTID Client ID
  • OAUTH_SECRET Client Secret
  • OAUTH_REDIRECT OAuth Callback URL (frontend host + /oauth/callback/)
mod_webui
  • OAUTH_JWTSECRET JWT Secret (something random)

Documentation

Overview

Package shodan provides core functionality for writing a Discord bot

Index

Constants

This section is empty.

Variables

View Source
var (
	// DiscordAuthTokenFormat describes the format used for the Authentication header used by discordgo
	DiscordAuthTokenFormat = "Bot %s"
)
View Source
var Loader = &ModuleLoader{
	Modules: []ModuleInstance{},
}

Loader is a singleton available from init functions of plugin packages and exposes a module loader

View Source
var VerifyJWTFunc func(string) (string, error) = func(t string) (string, error) {
	return "", WrapErrorHttp(errors.New("VerifyJWTFunc not overwritten, did you load mod_oauth?"), 500)
}

Functions

func DUFetchProfile

func DUFetchProfile(token string) (*discordgo.User, error)

DUFetchProfile fetches a users own profile using the provided token (DU: Do as User)

func DUGetUserGuilds

func DUGetUserGuilds(token string) ([]*discordgo.UserGuild, error)

DUGetUserGuild gets a users joined guilds using the provided token (DU: Do as User)

func Error

func Error(msg string) error

Error is a shorthand function to create a DebuggableError from a string

func ErrorHttp

func ErrorHttp(msg string, code int) error

ErrorHttp is a shorthand function to create a DebuggableError from a string and HTTP status code

func HttpForward

func HttpForward(w http.ResponseWriter, uri string)

HttpForward writes a 301 forward to the supplied uri via a ResponseWriter

func HttpSendError

func HttpSendError(w http.ResponseWriter, err error) error

HttpSendError sends a response to the given ResponseWriter and captures the error if given a DebuggableError

This function sends 500 Internal Server Error by default

func InitDiscord

func InitDiscord(token string) (*discordgo.Session, error)

InitDiscord sets up a discordgo session (but does not open a connection to a websocket)

func InitHTTP

func InitHTTP(addr string) (*mux.Router, error)

InitHTTP creates a new muxer and starts the HTTP listener

TODO: Reimplement support for disabling the listener

func InitPostgres

func InitPostgres(connStr string) (*sql.DB, error)

InitPostgres initializes the postgres service

func IsMention

func IsMention(needle string) bool

func MentionsMe

func MentionsMe(userID string, content string) bool

func ReportThreadError

func ReportThreadError(isFatal bool, error error)

ReportThreadError reports the current thread as failed, captures the error if it is debuggable and kills the goroutine

func Run

func Run()

Run invokes the main loop, core services like HTTP and discordgo.

Meant to be called from an external package after importing additional modules.

func SendResponse

func SendResponse(w http.ResponseWriter, res *ResponseEnvelope) error

SendResponse sends the given ResponseEnvelope to the ResponseWriter

func WrapError

func WrapError(e error) error

WrapError wraps any error into a DebuggableError. Never double-wraps. This function should only be used at module boundaries for performance reasons. Sets the HTTP status to 500 by default.

func WrapErrorHttp

func WrapErrorHttp(e error, code int) error

WrapErrorHttp wraps an existing error into a DebuggableError and attaches a status code to it

Types

type Command

type Command interface {
	GetNames() []string
	Invoke(invocation *CommandInvocation) error
}

The Command interface enables the implementer to be loaded as a command

type CommandInvocation

type CommandInvocation struct {
	Name      string
	Arguments []string
	Empty     bool
	Event     *discordgo.Message
	Shodan    Shodan
	Helpers   *CommandInvocationHelpers
}

A CommandInvocation contains all data (and references) the command stack parses from an incoming command

type CommandInvocationHelpers

type CommandInvocationHelpers struct {
	Reply      func(string) error
	ReplyEmbed func(*discordgo.MessageEmbed) error
}

CommandInvocationHelpers are attached to the CommandInvocation and provide easy access to frequently used functionality

type CommandStack

type CommandStack struct {
	FallbackCommand Command
	// contains filtered or unexported fields
}

The CommandStack holds an array of commands and an optional fallback command

func InitCommandStack

func InitCommandStack() (*CommandStack, error)

InitCommandStack creates a new CommandStack

func (*CommandStack) Attach

func (commandStack *CommandStack) Attach(shodan Shodan)

Attach the command stack to a shodan instance

func (*CommandStack) GetCommandList

func (commandStack *CommandStack) GetCommandList(includeAliases bool) map[string]Command

GetCommandList returns a map of all commands. The includeAliases variable determines if a command can have multiple entries, one for each alias. Otherwise only the first alias is returned

func (*CommandStack) RegisterCommand

func (commandStack *CommandStack) RegisterCommand(c Command)

RegisterCommand adds a command to the stack

type DebuggableError

type DebuggableError struct {
	Status int
	// contains filtered or unexported fields
}

DebuggableError implements Error and stores a HTTP status code and stack traces in addition to an error message.

func (*DebuggableError) Capture

func (e *DebuggableError) Capture()

Capture sends this error to Sentry for further analysis

func (*DebuggableError) Error

func (e *DebuggableError) Error() string

Error returns the error message

type KVS

type KVS interface {
	Set(string, string) error
	SetWithDefaultTTL(string, string) error
	Get(string) (string, error)
	HasKey(key string) (bool, error)
	Clear(string) error
}

KVS is the inteface for Key-Value-Stores

func InitRedis

func InitRedis(url string) (KVS, error)

InitRedis initializes the Redis KVS

type Module

type Module interface {
	GetIdentifier() string
	Attach(Shodan) error
}

A Module represents a loadable piece of code that has been added at compile-time Modules are, by nature of them being loaded though init(), global.

type ModuleInstance

type ModuleInstance struct {
	Module  Module
	Enabled bool
}

ModuleInstance holds a module and its current state.

This glue is needed because the Modules are global to the process.

type ModuleLoader

type ModuleLoader struct {
	Modules []ModuleInstance
}

A ModuleLoader holds ModuleInstances

func (*ModuleLoader) Attach

func (loader *ModuleLoader) Attach(session Shodan) error

Attach attaches enabled modules to the session.

After this point it does not matter if a module is marked as enabled or not in the ModuleInstance

func (*ModuleLoader) GetModuleList

func (loader *ModuleLoader) GetModuleList() map[string]bool

GetModuleList gets a map of all module names. The value of the map determines if the module is enabled or not.

func (*ModuleLoader) LoadModule

func (loader *ModuleLoader) LoadModule(m Module)

LoadModule adds a module to the loader. Modules are disabled by default.

type PermissionEnabledCommand

type PermissionEnabledCommand interface {
	GetRequiredPermission() int
}

PermissionEnabledCommand defines an interface Commands can implement to indicate the permission bits corresponding to discordgo ACLs required to run this command

type RedisKVS

type RedisKVS struct {
	// contains filtered or unexported fields
}

RedisKVS is the redis-implementation of KVS

func (*RedisKVS) Clear

func (r *RedisKVS) Clear(key string) error

Clear removes a key from the KVS

func (*RedisKVS) Get

func (r *RedisKVS) Get(key string) (string, error)

Get returns a key from the KVS, or an error if the key doesn't exist

func (*RedisKVS) HasKey

func (r *RedisKVS) HasKey(key string) (bool, error)

HasKey returns a boolean indicating if the key exists

func (*RedisKVS) Set

func (r *RedisKVS) Set(key string, value string) error

Set sets a key in the KVS permanently

func (*RedisKVS) SetWithDefaultTTL

func (r *RedisKVS) SetWithDefaultTTL(key string, value string) error

SetWithDefaultTTL sets a key with the default expiry timer

type RequestEnvelope

type RequestEnvelope struct {
	Data  []byte
	Token string
}

RequestEnvelope wraps a HTTP request to the SHODAN-API

func ReadRequest

func ReadRequest(r *http.Request) (*RequestEnvelope, error)

ReadRequest reads the given Request and converts it into a standard API request

func (*RequestEnvelope) Authenticated

func (req *RequestEnvelope) Authenticated() bool

Checks if a token is provided. Because ReadRequest will fail if a token is provided, but doesn't validate, no further checking is required; this is a cheap call.

type ResponseEnvelope

type ResponseEnvelope struct {
	Status int32       `json:"status"`
	Error  string      `json:"err"`
	Data   interface{} `json:"data"`
}

ResponseEnvelope wraps a HTTP respone from the SHODAN-API

type Shodan

type Shodan interface {
	GetDiscord() *discordgo.Session
	GetDatabase() *sql.DB
	GetMux() *mux.Router
	GetCommandStack() *CommandStack
	GetRedis() KVS
}

type ThreadError

type ThreadError struct {
	IsFatal bool
	Error   error
}

A ThreadError wraps an error that occured in another thread, indicating if the error was fatal and the application should be terminated

Directories

Path Synopsis
bin
modules
log

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL