Skip to content

Commit

Permalink
Merge pull request #156 from hairyhenderson/base64-funcs-155
Browse files Browse the repository at this point in the history
Adding new base64.Encode/base64.Decode functions
  • Loading branch information
hairyhenderson authored Jun 9, 2017
2 parents cac0bc6 + 40480c4 commit cb5450a
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 0 deletions.
25 changes: 25 additions & 0 deletions base64/base64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package base64

import (
b64 "encoding/base64"
"log"
)

// Encode - Encode data in base64 format
func Encode(in []byte) string {
return b64.StdEncoding.EncodeToString(in)
}

// Decode - Decode a base64-encoded string
func Decode(in string) []byte {
o, err := b64.StdEncoding.DecodeString(in)
if err != nil {
// maybe it's in the URL variant?
o, err = b64.URLEncoding.DecodeString(in)
if err != nil {
// ok, just give up...
log.Fatal(err)
}
}
return o
}
27 changes: 27 additions & 0 deletions base64/base64_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package base64

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestEncode(t *testing.T) {
assert.Equal(t, "", Encode([]byte("")))
assert.Equal(t, "Zg==", Encode([]byte("f")))
assert.Equal(t, "Zm8=", Encode([]byte("fo")))
assert.Equal(t, "Zm9v", Encode([]byte("foo")))
assert.Equal(t, "Zm9vYg==", Encode([]byte("foob")))
assert.Equal(t, "Zm9vYmE=", Encode([]byte("fooba")))
assert.Equal(t, "Zm9vYmFy", Encode([]byte("foobar")))
}

func TestDecode(t *testing.T) {
assert.Equal(t, []byte(""), Decode(""))
assert.Equal(t, []byte("f"), Decode("Zg=="))
assert.Equal(t, []byte("fo"), Decode("Zm8="))
assert.Equal(t, []byte("foo"), Decode("Zm9v"))
assert.Equal(t, []byte("foob"), Decode("Zm9vYg=="))
assert.Equal(t, []byte("fooba"), Decode("Zm9vYmE="))
assert.Equal(t, []byte("foobar"), Decode("Zm9vYmFy"))
}
64 changes: 64 additions & 0 deletions docs/content/functions/base64.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: base64 functions
menu:
main:
parent: functions
---

## `base64.Encode`

Encode data as a Base64 string. Specifically, this uses the standard Base64 encoding as defined in [RFC4648 §4](https://tools.ietf.org/html/rfc4648#section-4) (and _not_ the URL-safe encoding).

### Usage

```go
base64.Encode input
```

### Arguments

| name | description |
|--------|-------|
| `input` | The data to encode. Can be a string, a byte array, or a buffer. Other types will be converted to strings first. |

### Examples

```console
$ gomplate -i '{{ base64.Encode "hello world" }}'
aGVsbG8gd29ybGQ=
```

```console
$ gomplate -i '{{ "hello world" | base64.Encode }}'
aGVsbG8gd29ybGQ=
```

## `base64.Decode`

Decode a Base64 string. This supports both standard ([RFC4648 §4](https://tools.ietf.org/html/rfc4648#section-4)) and URL-safe ([RFC4648 §5](https://tools.ietf.org/html/rfc4648#section-5)) encodings.

This implementation outputs the data as a string, so it may not be appropriate for decoding binary data. If this functionality is desired, [file an issue](https://github.com/hairyhenderson/gomplate/issues/new).

### Usage

```go
base64.Decode input
```

### Arguments

| name | description |
|--------|-------|
| `input` | The base64 string to decode |

### Examples

```console
$ gomplate -i '{{ base64.Decode "aGVsbG8gd29ybGQ=" }}'
hello world
```

```console
$ gomplate -i '{{ "aGVsbG8gd29ybGQ=" | base64.Decode }}'
hello world
```
1 change: 1 addition & 0 deletions funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,6 @@ func initFuncs(data *Data) template.FuncMap {
"include": data.include,
}
funcs.AWSFuncs(f)
funcs.AddBase64Funcs(f)
return f
}
84 changes: 84 additions & 0 deletions funcs/base64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package funcs

import (
"fmt"
"strconv"
"sync"

"github.com/hairyhenderson/gomplate/base64"
)

var (
bf *Base64Funcs
bfInit sync.Once
)

// Base64NS - the base64 namespace
func Base64NS() *Base64Funcs {
bfInit.Do(func() { bf = &Base64Funcs{} })
return bf
}

// AddBase64Funcs -
func AddBase64Funcs(f map[string]interface{}) {
f["base64"] = Base64NS
}

// Base64Funcs -
type Base64Funcs struct{}

// Encode -
func (f *Base64Funcs) Encode(in interface{}) string {
b := toBytes(in)
return base64.Encode(b)
}

// Decode -
func (f *Base64Funcs) Decode(in interface{}) string {
return string(base64.Decode(toString(in)))
}

type byter interface {
Bytes() []byte
}

func toBytes(in interface{}) []byte {
if in == nil {
return []byte{}
}
if s, ok := in.([]byte); ok {
return s
}
if s, ok := in.(byter); ok {
return s.Bytes()
}
if s, ok := in.(string); ok {
return []byte(s)
}
return []byte(fmt.Sprintf("%s", in))
}

func toString(in interface{}) string {
if s, ok := in.(string); ok {
return s
}
if s, ok := in.(fmt.Stringer); ok {
return s.String()
}
if i, ok := in.(int); ok {
return strconv.Itoa(i)
}
if u, ok := in.(uint64); ok {
return strconv.FormatUint(u, 10)
}
if f, ok := in.(float64); ok {
return strconv.FormatFloat(f, 'f', -1, 64)
}
if b, ok := in.(bool); ok {
return strconv.FormatBool(b)
}
if in == nil {
return "nil"
}
return fmt.Sprintf("%s", in)
}
30 changes: 30 additions & 0 deletions funcs/base64_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package funcs

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
)

func TestBase64Encode(t *testing.T) {
bf := &Base64Funcs{}
assert.Equal(t, "Zm9vYmFy", bf.Encode("foobar"))
}

func TestBase64Decode(t *testing.T) {
bf := &Base64Funcs{}
assert.Equal(t, "foobar", bf.Decode("Zm9vYmFy"))
// assert.Equal(t, "", bf.Decode(nil))
}

func TestToBytes(t *testing.T) {
assert.Equal(t, []byte{0, 1, 2, 3}, toBytes([]byte{0, 1, 2, 3}))

buf := &bytes.Buffer{}
buf.WriteString("hi")
assert.Equal(t, []byte("hi"), toBytes(buf))

assert.Equal(t, []byte{}, toBytes(nil))

}
25 changes: 25 additions & 0 deletions test/integration/base64.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bats

load helper

tmpdir=$(mktemp -u)

function setup () {
mkdir -p $tmpdir
}

function teardown () {
rm -rf $tmpdir
}

@test "'base64.Encode'" {
gomplate -i '{{ "foo" | base64.Encode }}'
[ "$status" -eq 0 ]
[[ "${output}" == "Zm9v" ]]
}

@test "'base64.Decode'" {
gomplate -i '{{ "Zm9v" | base64.Decode }}'
[ "$status" -eq 0 ]
[[ "${output}" == "foo" ]]
}

0 comments on commit cb5450a

Please sign in to comment.