-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add example application
- Loading branch information
Showing
8 changed files
with
163 additions
and
86 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 @@ | ||
/cmd/example1/example1 |
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,23 @@ | ||
.DEFAULT_GOAL := help | ||
|
||
.PHONY: help test | ||
|
||
test: ## Runs tests | ||
go test | ||
|
||
run-example1: clean ## Runs sample app | ||
@echo "* Creating docker container with PostgreSQL" | ||
docker run --name umbrella-example1 -d -e POSTGRES_PASSWORD=upass -e POSTGRES_USER=uuser -e POSTGRES_DB=udb -p 54321:5432 postgres:13 | ||
@echo "* Sleeping for 10 seconds to give database time to initialize..." | ||
@sleep 10 | ||
@echo "* Building and starting application..." | ||
cd cmd/example1 && go build . | ||
cd cmd/example1 && ./example1 | ||
@echo "* Removing previously created docker container..." | ||
|
||
|
||
clean: ## Removes all created dockers | ||
docker rm -f umbrella-example1 | ||
|
||
help: ## Displays this help | ||
@awk 'BEGIN {FS = ":.*##"; printf "$(MAKEFILE_NAME)\n\nUsage:\n make \033[1;36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[1;36m%-25s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) |
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 |
---|---|---|
|
@@ -15,45 +15,26 @@ Package umbrella provides a simple authentication mechanism for an HTTP endpoint | |
5. [Motivation](#motivation) | ||
|
||
## Sample code | ||
The following code snippet shows how the module can be used. | ||
|
||
```go | ||
// database connection | ||
dbConn, _ = sql.Open("postgres", "host=localhost user=myuser password=mypass port=5432 dbname=mydb sslmode=disable") | ||
|
||
// umbrella controller | ||
u := NewUmbrella(dbConn, "tblprefix_", &JWTConfig{ | ||
Key: "SomeSecretKey--.", | ||
Issuer: "SomeIssuer", | ||
ExpirationMinutes: 15, | ||
}, nil) | ||
|
||
// create db tables | ||
_ := u.CreateDBTables() | ||
|
||
// http server | ||
// uri with registration, activation, login (returns auth token), logout endpoint | ||
http.Handle("/umbrella/", u.GetHTTPHandler("/umbrella/")) | ||
// restricted stuff that requires signing in (a token in http header) | ||
http.Handle("/restricted_stuff/", u.GetHTTPHandlerWrapper( | ||
getRestrictedStuffHTTPHandler(), | ||
umbrella.HandlerConfig{}, | ||
)) | ||
http.ListenAndServe(":8001", nil) | ||
|
||
// wrap http handler with a check for logged user | ||
func getRestrictedStuffHTTPHandler() http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
userID := umbrella.GetUserIDFromRequest(r) | ||
if userID != 0 { | ||
w.WriteHeader(http.StatusOK) | ||
w.Write([]byte("RestrictedAreaContent")) | ||
} else { | ||
w.WriteHeader(http.StatusUnauthorized) | ||
w.Write([]byte("NoAccess")) | ||
} | ||
}) | ||
} | ||
A working application can be found in the `cmd/example1`. Type `make run-example1` to start an HTTP server and check the endpoints as shown below. jq is used to parse out the token from JSON output, however, it can be done manually as well. | ||
|
||
```bash | ||
# run the application | ||
% make run-example1 | ||
# ...some output... | ||
|
||
# sign in to get a token | ||
% UMB_TOKEN=$(curl -s -X POST -d "[email protected]&password=admin" http://localhost:8001/umbrella/login | jq -r '.data.token') | ||
|
||
# call restricted endpoint without the token | ||
% curl http://localhost:8001/secret_stuff/ | ||
YouHaveToBeLoggedIn | ||
|
||
# call it again with token | ||
% curl -H "Authorization: Bearer $UMB_TOKEN" http://localhost:8001/secret_stuff/ | ||
SecretStuffOnlyForAdmin% | ||
|
||
# remove temporary postgresql docker | ||
make clean | ||
``` | ||
|
||
## Database connection | ||
|
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,72 @@ | ||
package main | ||
|
||
import ( | ||
"database/sql" | ||
"log" | ||
"net/http" | ||
|
||
"github.com/go-phings/umbrella" | ||
_ "github.com/lib/pq" | ||
) | ||
|
||
const dbDSN = "host=localhost user=uuser password=upass port=54321 dbname=udb sslmode=disable" | ||
const tblPrefix = "p_" | ||
|
||
func main() { | ||
db, err := sql.Open("postgres", dbDSN) | ||
if err != nil { | ||
log.Fatal("Error connecting to db") | ||
} | ||
|
||
// create umbrella controller | ||
u := *umbrella.NewUmbrella(db, tblPrefix, &umbrella.JWTConfig{ | ||
Key: "someSecretKey", | ||
Issuer: "someIssuer", | ||
ExpirationMinutes: 15, | ||
}, &umbrella.UmbrellaConfig{ | ||
TagName: "ui", | ||
}) | ||
|
||
// create database tables | ||
err = u.CreateDBTables() | ||
if err != nil { | ||
log.Fatalf("error creating database tables: %s", err.Error()) | ||
} | ||
|
||
// create admin user | ||
key, err := u.CreateUser("[email protected]", "admin", map[string]string{ | ||
"Name": "admin", | ||
}) | ||
if err != nil { | ||
log.Fatalf("error with creating admin: %s", err.Error()) | ||
} | ||
err = u.ConfirmEmail(key) | ||
if err != nil { | ||
log.Fatalf("error with confirming admin email: %s", err.Error()) | ||
} | ||
|
||
// /umbrella/{login,logout,register,confirm} | ||
http.Handle("/umbrella/", u.GetHTTPHandler("/umbrella/")) | ||
|
||
// secret stuff | ||
http.Handle("/secret_stuff/", u.GetHTTPHandlerWrapper(secretStuff(), umbrella.HandlerConfig{})) | ||
|
||
log.Fatal(http.ListenAndServe(":8001", nil)) | ||
} | ||
|
||
func secretStuff() http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
userID := umbrella.GetUserIDFromRequest(r) | ||
switch userID { | ||
case 1: | ||
w.WriteHeader(http.StatusOK) | ||
w.Write([]byte("SecretStuffOnlyForAdmin")) | ||
case 0: | ||
w.WriteHeader(http.StatusUnauthorized) | ||
w.Write([]byte("YouHaveToBeLoggedIn")) | ||
default: | ||
w.WriteHeader(http.StatusOK) | ||
w.Write([]byte("SecretStuffForOtherUser")) | ||
} | ||
}) | ||
} |
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
Oops, something went wrong.