package module
Version: v0.0.0-...-e11f1d1 Latest Latest

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

Go to latest
Published: Jan 24, 2021 License: BSD-3-Clause Imports: 7 Imported by: 0



membersys is a web service for applying for membership in an organization, written for the Starship Factory.


membersys is relatively self-sufficient. It can run in a doozer-anonymous-port setting, but that Doozer dependency is optional except for compiling. Other than that it can run on any networked host.


For building, you will need to install the doozer-exportedservice Go package first. Under Debian GNU/Linux, this can be done by running the following command as root:

% apt-get install golang-doozer-exportedservice-dev

Under other systems, you can copy the source files to ${GOPATH}/src/

Once this is done, run

% go build

in order to get a working binary. It will be called membersys and will be statically linked, so you can just use it anywhere.


For installing, you will have to copy the form.html and printlayout.html files as well as the css and js directory into the destination template directory, such as /usr/local/share/membersys. Then, copy the binary you built previously to the destination binary directory, e.g. /usr/local/bin.

Then you can run the binary and pass it the --template-dir flag, pointing to the directory where you installed the templates, e.g.

% /usr/local/bin/membersys --template-dir=/usr/local/share/membersys


If you want to use membersys productively, it is recommended that you use a separate program to launch it and redirect all output to logs. Currently, membersys doesn't daemonize, so it will always run in the foreground. Using a tool like run-as-daemon will work around this easily.


Like any good Go program, membersys exports a few variables under /debug/vars:

  • num-http-requests: the total number of HTTP requests received by the binary, including requests for favicon.ico, CSS and JS files, etc.
  • num-successful-form-submissions: number of times the request form has been filled out correctly and submitted.
  • num-form-submission-errors: maps by error type the different reasons why requests have been rejected (e.g. no name was specified), and how many requests of the type have been rejected.


For future releases, we are planning to add the following features:

For release 0.2, we plan to store all successfully submitted requests in an Apache Cassandra database. The print form will get a barcode with the row ID of the record, making the record easier to find using a barcode scanner.

Release 0.3 will get mail verification functionality. Applicants will receive an e-mail to the address they provided, and requests will only be considered when a link given in the e-mail has been followed.

Release 1.0 will get administrative functionality for authenticated users. If they are identified to be in a given scope, they will be able to accept or reject applicants from the web interface. Applicants can either be searched for by given criteria or looked up directly by their row ID, which can be scanned from the printed form using a barcode scanner.


Bugs for this project are tracked using ditz in the source code tree itself. The current state of bug squashing can be viewed at

To report bugs, either send a pull request with the ditz bug added to the project starship-factory/membersys on GitHub, or send an e-mail to the Starship Factory open list.




This section is empty.


This section is empty.


This section is empty.


type FormInputData

type FormInputData struct {
	MemberData *Member
	Metadata   *MembershipMetadata
	Key        string
	CommonErr  string
	FieldErr   map[string]string

Data used by the HTML template. Contains not just data entered so far, but also some error texts in case there was a problem submitting data.

type MemberWithKey

type MemberWithKey struct {
	Key string `json:"key"`

type MembershipAgreementWithKey

type MembershipAgreementWithKey struct {
	Key string `json:"key"`

type MembershipDB

type MembershipDB interface {
	StoreMembershipRequest(context.Context, *FormInputData) (string, error)
	GetMemberDetailByUsername(context.Context, string) (*MembershipAgreement, error)
	GetMemberDetail(context.Context, string) (*MembershipAgreement, error)
	SetMemberFee(context.Context, string, uint64, bool) error
	SetLongValue(context.Context, string, string, uint64) error
	SetBoolValue(context.Context, string, string, bool) error
	SetTextValue(context.Context, string, string, string) error
	GetMembershipRequest(context.Context, string) (*MembershipAgreement, error)
	StreamingEnumerateMembers(context.Context, string, int32, chan<- *Member, chan<- error)
	EnumerateMembers(context.Context, string, int32) ([]*Member, error)
	StreamingEnumerateMembershipRequests(context.Context, string, string, int32, chan<- *MembershipAgreementWithKey, chan<- error)
	EnumerateMembershipRequests(context.Context, string, string, int32) ([]*MembershipAgreementWithKey, error)
	StreamingEnumerateQueuedMembers(context.Context, string, int32, chan<- *MemberWithKey, chan<- error)
	EnumerateQueuedMembers(context.Context, string, int32) ([]*MemberWithKey, error)
	StreamingEnumerateDeQueuedMembers(context.Context, string, int32, chan<- *MemberWithKey, chan<- error)
	EnumerateDeQueuedMembers(context.Context, string, int32) ([]*MemberWithKey, error)
	StreamingEnumerateTrashedMembers(context.Context, string, int32, chan<- *MemberWithKey, chan<- error)
	EnumerateTrashedMembers(context.Context, string, int32) ([]*MemberWithKey, error)
	MoveMemberToTrash(context.Context, string, string, string) error
	MoveNewMemberToFullMember(context.Context, *MemberWithKey) error
	MoveDeletedMemberToArchive(context.Context, *MemberWithKey) error
	MoveApplicantToNewMember(context.Context, string, string) error
	MoveApplicantToTrash(context.Context, string, string) error
	MoveQueuedRecordToTrash(context.Context, string, string) error
	StoreMembershipAgreement(context.Context, string, []byte) error

type WelcomeMail

type WelcomeMail struct {
	// contains filtered or unexported fields

func NewWelcomeMail

func NewWelcomeMail(config *config.WelcomeMailConfig) (*WelcomeMail, error)

func (*WelcomeMail) SendMail

func (w *WelcomeMail) SendMail(member *Member) error

Sends a welcome e-mail to the new member.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL