-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement JWT validation (support for HMAC/RSA)
- Loading branch information
Alex Sch
committed
Aug 25, 2020
1 parent
1c1266f
commit 88ac7df
Showing
44 changed files
with
3,484 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Functions | ||
|
||
This example uses the functions and HTTP implementations to call the API endpoints at [jsonplaceholder.typicode.com](https://jsonplaceholder.typicode.com/). | ||
|
||
# Getting started | ||
|
||
You could get started by executing the `main.go` file. | ||
|
||
```bash | ||
$ go run main.go | ||
``` | ||
|
||
Once Semaphore is up and running you could execute the `todo` flow by calling the service on port `8080`. | ||
|
||
```bash | ||
$ curl 127.0.0.1:8080/ -H 'Authorization: super-secret' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
endpoint "FetchLatestProject" "http" { | ||
endpoint = "/" | ||
method = "GET" | ||
codec = "json" | ||
} | ||
|
||
error "proto.Error" { | ||
value = "some message" | ||
status = 400 | ||
} | ||
|
||
flow "FetchLatestProject" { | ||
input "proto.Query" { | ||
header = ["Authorization"] | ||
} | ||
|
||
error "proto.Unauthorized" { | ||
message = "{{ error:message }}" | ||
status = "{{ error:status }}" | ||
} | ||
|
||
on_error { | ||
status = 401 | ||
message = "on error message" | ||
} | ||
|
||
before { | ||
resources { | ||
claims = "{{ jwt(input.header:Authorization) }}" | ||
} | ||
} | ||
|
||
resource "query" { | ||
request "proto.Service" "GetTodo" {} | ||
} | ||
|
||
resource "user" { | ||
request "proto.Service" "GetUser" {} | ||
} | ||
|
||
output "proto.Item" { | ||
header { | ||
Username = "{{ user:username }}" | ||
} | ||
|
||
id = "{{ query:id }}" | ||
title = "{{ query:title }}" | ||
completed = "{{ query:completed }}" | ||
claimer_id = "{{ claims:subject }}" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package main | ||
|
||
import ( | ||
dgrijalva "github.com/dgrijalva/jwt-go" | ||
"github.com/jexia/semaphore" | ||
"github.com/jexia/semaphore/cmd/semaphore/daemon" | ||
"github.com/jexia/semaphore/cmd/semaphore/daemon/providers" | ||
"github.com/jexia/semaphore/pkg/broker" | ||
"github.com/jexia/semaphore/pkg/broker/logger" | ||
"github.com/jexia/semaphore/pkg/codec/json" | ||
"github.com/jexia/semaphore/pkg/codec/proto" | ||
"github.com/jexia/semaphore/pkg/functions" | ||
"github.com/jexia/semaphore/pkg/functions/lib/jwt" | ||
"github.com/jexia/semaphore/pkg/providers/hcl" | ||
"github.com/jexia/semaphore/pkg/providers/protobuffers" | ||
"github.com/jexia/semaphore/pkg/transport/http" | ||
) | ||
|
||
// Claims is a custom implementation of lib/jwt.Claims interface. | ||
type Claims struct{ dgrijalva.StandardClaims } | ||
|
||
// Subject is a method returning subject (to satisfy Claims interface). | ||
func (c Claims) Subject() string { return c.StandardClaims.Subject } | ||
|
||
// NewClaims instantiates a new claims object. | ||
func NewClaims() jwt.Claims { return new(Claims) } | ||
|
||
func main() { | ||
var ( | ||
reader = jwt.HMAC("very-strong-secret") | ||
ctx = logger.WithLogger(broker.NewContext()) | ||
functions = functions.Custom{ | ||
"jwt": jwt.JWT(reader, NewClaims), | ||
} | ||
) | ||
|
||
core, err := semaphore.NewOptions(ctx, | ||
semaphore.WithLogLevel("*", "debug"), | ||
semaphore.WithFlows(hcl.FlowsResolver("./*.hcl")), | ||
semaphore.WithCodec(json.NewConstructor()), | ||
semaphore.WithCodec(proto.NewConstructor()), | ||
semaphore.WithCaller(http.NewCaller()), | ||
semaphore.WithFunctions(functions), | ||
) | ||
|
||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
options, err := providers.NewOptions(ctx, core, | ||
providers.WithEndpoints(hcl.EndpointsResolver("./*.hcl")), | ||
providers.WithSchema(protobuffers.SchemaResolver([]string{"./proto"}, "./proto/*.proto")), | ||
providers.WithServices(protobuffers.ServiceResolver([]string{"./proto"}, "./proto/*.proto")), | ||
providers.WithListener(http.NewListener(":8080")), | ||
) | ||
|
||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
client, err := daemon.NewClient(ctx, core, options) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
if err := client.Serve(); err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# API | ||
|
||
This package contains API artifacts such as protobuf annotations. | ||
|
||
## Protobuf Usage | ||
|
||
1. Define your [gRPC](https://grpc.io/docs/) service using protocol buffers | ||
|
||
`your_service.proto`: | ||
```protobuf | ||
syntax = "proto3"; | ||
package example; | ||
message StringMessage { | ||
string value = 1; | ||
} | ||
service YourService { | ||
rpc Echo(StringMessage) returns (StringMessage) {} | ||
} | ||
``` | ||
|
||
2. Add a [`semaphore.api`](https://github.com/jexia/semaphore/blob/master/api/annotations.proto) | ||
annotation to your .proto file | ||
|
||
`your_service.proto`: | ||
```diff | ||
syntax = "proto3"; | ||
package example; | ||
+ | ||
+import "semaphore/api/annotations.proto"; | ||
+ | ||
message StringMessage { | ||
string value = 1; | ||
} | ||
|
||
service YourService { | ||
+ option (semaphore.api.service) = { | ||
+ host: "127.0.0.1:80" | ||
+ transport: "http" | ||
+ codec: "json" | ||
+ }; | ||
+ | ||
- rpc Echo(StringMessage) returns (StringMessage) {} | ||
+ rpc Echo(StringMessage) returns (StringMessage) { | ||
+ option (semaphore.api.http) = { | ||
+ post: "/v1/example/echo" | ||
+ body: "*" | ||
+ }; | ||
+ } | ||
} | ||
``` | ||
|
||
>You will need to provide the required third party protobuf files to the `protoc` compiler. | ||
>They are included in this repo under the `api` folder, and we recommend copying | ||
>them into your `protoc` generation file structure. If you've structured your protofiles according | ||
>to something like [the Buf style guide](https://buf.build/docs/style-guide#files-and-packages), | ||
>you could copy the files into a top-level `./semaphore` folder. | ||
If you do not want to modify the proto file for use with grpc-gateway you can | ||
alternatively use an external | ||
[Service Configuration](https://github.com/jexia/semaphore/tree/master/cmd/semaphore/config) file. | ||
[Check our documentation](https://jexia.gitbook.io/semaphore/getting-started/cli) | ||
for more information. | ||
|
||
3. Write flow your definitions as usual |
Oops, something went wrong.