csrf

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: May 1, 2021 License: MIT Imports: 7 Imported by: 0

README

cleango

release

A template Go module, making it easy to start projects with consistent structure. Use the button above "Use this template" to get your Go project off to a clean start.

  • Leans on clean architecture
  • Implements tests
  • Build tags
  • CI via GitHub Actions workflow
Motivation

My aim with this repo is to give myself a template to copy, each time I start a new project in Go.

Underlying this I have, over the years, been living with various languages to try and find one that's fast to prototype whilst also being type safe. I'm liking Go, and this template is an attempt to create a pattern for structuring Go projects loose-ishly based on Clean Architecture.

Clean Architecture has lofty aims. There aren't many resources out there that lay it out in Go. I don't either, because Go doesn't map directly, or my projects don't fit neatly.

But I am interested in architecture that makes testing easy, so I persisted. As a nice bonus I found it easy and fast to build APIs, because the architecture made it so.

So take this as a pragmatic approach to Clean Architecture using Go.

Notes

Some notes on the code, or style, or implications. I'm not a great Go coder, I'm still learning. These notes are aimed at other learners.

Feedback is very much hoped for, to make this template and my Go-skills better.

Build Tags

I love build tags. This is a big win when using Go, because it's easy to switch config.

$ go run -tags dev api/server.go
2021/04/21 22:03:52 webserver.Start(): listening on port 8080

Here is an example that says include this file when -tags is dev or test. And in the GitHub action, here I run test with that tag. Pulling in that particular file.

This is good because if you're test want to run quicker, you can set low limits for various things.

Passing Database Connection

This was a big challenge, as it is in most languages. I found a solution which made a lot of sense, and fits right in with Clean Architecture. It also makes testing and mocks really easy.

There are a lot of frameworks for http handling. I dislike frameworks because they add dependencies, which often add more complexity that you need. So here I use an Env struct to reference Service pointers. This allows seamless passing of the datastore connection (or mock) to the handlers.

I mashed up the Clean Architecture style with this blog post. That's where my Env struct came from.

Use Case

Usecase is a core Clean Architecture idea, and a little vague. I think of it as, 'an action that happens, like making a coffee.' There's often multiple steps to produce an outcome. An http handler depends on a usecase, but the usecase knows nothing about the http handler.

The usecase is also where I implement my datastore mocks. Mock come after Interface.

Interface

The interface for a usecase is imported by the datastore, don't repeat yourself. Interfaces in Go make code simpler and more robust, so learn interfaces.

This is where the datastore interface references the usecase interface.

Mocks

Mocks, I love mocks. But mocking datastores and methods somehow always seems confusing.

To be clear, I'm mocking the datastore methods. When my usecase makes a call to a datastore method, when testing it's my mocks that are injected.

Here is the mock method, it mocks the call to the datastore method. I have conditionals here, to simulate responses from the real method here.

And here's another thing. From a higher level method, I'm using data that triggers the mock to respond in a particular way for testing. This might not be pure, but it's very handy and cuts down on a lot of mocking code.

I spent a lot of time figuring out mocking, in various languages. Using Go, Clean Architecture, Env struct, etc, are where I'm currently at. And it works well like this, without too much duplicate testing code.

Wider point. Tests are not for 'production code', they are for all code. Tests make your development quicker overall. For years I thought tests were a hassle getting in the way of writing code. If you're still thinking that, read The Tortoise and the Hare.

File Numbering

I use file name numbering for files that are part of the templating pattern. This is purely to make scanning dirs and finding what you expect to always be there much quicker.

For example:

$ ls -l pkg/usecase/enablething 
total 56
-rw-r--r--  1 thisdougb  staff  209 21 Apr 20:13 1_interface.go
-rw-r--r--  1 thisdougb  staff  181 21 Apr 20:14 2_service.go
-rw-r--r--  1 thisdougb  staff  179 21 Apr 19:43 3_mock.go
-rw-r--r--  1 thisdougb  staff   77 21 Apr 19:43 4_mock_reader.go
-rw-r--r--  1 thisdougb  staff  378 21 Apr 20:17 5_mock_writer.go
-rw-r--r--  1 thisdougb  staff  433 21 Apr 20:57 main.go
-rw-r--r--  1 thisdougb  staff  899 21 Apr 20:15 main_test.go

Documentation

Index

Constants

View Source
const (
	SaltsEnvKey = "CSRF_SALTS" // some flexibility in naming the container env key
	TokenLen    = 32

	N      = 1 << 15
	R      = 8
	P      = 1
	KeyLen = 32
)

Variables

This section is empty.

Functions

func Generate

func Generate() (string, string, error)

func GenerateWithToken added in v0.1.1

func GenerateWithToken(token string) (string, string, error)

func Validate

func Validate(inputToken string, inputHash string) (bool, int)

Types

This section is empty.

Jump to

Keyboard shortcuts

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