Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

Commit

Permalink
Merge branch 'main' into chore/update_dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
rot1024 committed Apr 11, 2022
2 parents 3f203d2 + db6ff77 commit 1aefdfc
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 49 deletions.
6 changes: 4 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# General
PORT=8080
REEARTH_DB=mongodb://localhost
REEARTH_HOST=https://localhost:8080
REEARTH_HOST_WEB=https://localhost:3000
REEARTH_DEV=false

# GCP
Expand Down Expand Up @@ -35,13 +37,13 @@ REEARTH_AUTHSRV_KEY=abcdefghijklmnopqrstuvwxyz
# Available mailers: [log, smtp, sendgrid]
REEARTH_MAILER=log

#SendGrid config
# SendGrid config
#REEARTH_MAILER=sendgrid
#REEARTH_SENDGRID_EMAIL=noreplay@test.com
#REEARTH_SENDGRID_NAME=
#REEARTH_SENDGRID_API=

#SMTP config
# SMTP config
#REEARTH_MAILER=smtp
#REEARTH_SMTP_EMAIL=noreplay@test.com
#REEARTH_SMTP_HOST=smtp.sendgrid.net
Expand Down
51 changes: 50 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,56 @@
# Changelog
All notable changes to this project will be documented in this file.

## 0.5.0 - 2022-02-22
## 0.6.0 - 2022-04-08

### 🚀 Features

- Authentication system ([#108](https://github.com/reearth/reearth-backend/pull/108)) [`b89c32`](https://github.com/reearth/reearth-backend/commit/b89c32)
- Default mailer that outputs mails into stdout [`aab26c`](https://github.com/reearth/reearth-backend/commit/aab26c)
- Assets filtering & pagination ([#81](https://github.com/reearth/reearth-backend/pull/81)) [`739943`](https://github.com/reearth/reearth-backend/commit/739943)
- Support sign up with information provided by OIDC providers ([#130](https://github.com/reearth/reearth-backend/pull/130)) [`fef60e`](https://github.com/reearth/reearth-backend/commit/fef60e)

### 🔧 Bug Fixes

- Load auth client domain from config ([#124](https://github.com/reearth/reearth-backend/pull/124)) [`9bde8a`](https://github.com/reearth/reearth-backend/commit/9bde8a)
- Signup fails when password is not set [`27c2f0`](https://github.com/reearth/reearth-backend/commit/27c2f0)
- Logger panics [`d1e3a8`](https://github.com/reearth/reearth-backend/commit/d1e3a8)
- Set auth server dev mode automatically [`83a66a`](https://github.com/reearth/reearth-backend/commit/83a66a)
- Auth server bugs and auth client bugs ([#125](https://github.com/reearth/reearth-backend/pull/125)) [`ce2309`](https://github.com/reearth/reearth-backend/commit/ce2309)
- Auth0 setting is not used by JWT verification middleware [`232e75`](https://github.com/reearth/reearth-backend/commit/232e75)
- Invalid mongo queries of pagination [`7caf68`](https://github.com/reearth/reearth-backend/commit/7caf68)
- Auth config not loaded expectedly [`570fe7`](https://github.com/reearth/reearth-backend/commit/570fe7)
- Users cannot creates a new team and scene [`5df25f`](https://github.com/reearth/reearth-backend/commit/5df25f)
- Auth server certificate is not saved as pem format [`982a71`](https://github.com/reearth/reearth-backend/commit/982a71)
- Repo filters are not merged expectedly [`f4cc3f`](https://github.com/reearth/reearth-backend/commit/f4cc3f)
- Auth is no longer required for GraphQL endpoint [`58a6d1`](https://github.com/reearth/reearth-backend/commit/58a6d1)
- Rename auth srv default client ID ([#128](https://github.com/reearth/reearth-backend/pull/128)) [`89adc3`](https://github.com/reearth/reearth-backend/commit/89adc3)
- Signup API is disabled when auth server is disabled, users and auth requests in mongo cannot be deleted ([#132](https://github.com/reearth/reearth-backend/pull/132)) [`47be6a`](https://github.com/reearth/reearth-backend/commit/47be6a)
- Auth to work with zero config ([#131](https://github.com/reearth/reearth-backend/pull/131)) [`3cbb45`](https://github.com/reearth/reearth-backend/commit/3cbb45)
- Property.SchemaListMap.List test fails [`3e6dff`](https://github.com/reearth/reearth-backend/commit/3e6dff)
- Errors when auth srv domain is not specified [`10691a`](https://github.com/reearth/reearth-backend/commit/10691a)
- Errors when auth srv domain is not specified [`648073`](https://github.com/reearth/reearth-backend/commit/648073)
- Login redirect does not work [`cb6ca4`](https://github.com/reearth/reearth-backend/commit/cb6ca4)
- Enable auth srv dev mode when no domain is specified [`0c0e28`](https://github.com/reearth/reearth-backend/commit/0c0e28)
- Add a trailing slash to jwt audiences [`e96f78`](https://github.com/reearth/reearth-backend/commit/e96f78)
- Allow separate auth server ui domain [`0ce79f`](https://github.com/reearth/reearth-backend/commit/0ce79f)

### ⚡️ Performance

- Reduce database queries to obtain scene IDs ([#119](https://github.com/reearth/reearth-backend/pull/119)) [`784332`](https://github.com/reearth/reearth-backend/commit/784332)

### ✨ Refactor

- Remove filter args from repos to prevent implementation errors in the use case layer ([#122](https://github.com/reearth/reearth-backend/pull/122)) [`82cf28`](https://github.com/reearth/reearth-backend/commit/82cf28)
- Http api to export layers [`3f2582`](https://github.com/reearth/reearth-backend/commit/3f2582)

### Miscellaneous Tasks

- Update dependencies ([#117](https://github.com/reearth/reearth-backend/pull/117)) [`d1a38e`](https://github.com/reearth/reearth-backend/commit/d1a38e)
- Update docker-compose config [`83f9b1`](https://github.com/reearth/reearth-backend/commit/83f9b1)
- Add log for GraphQL Playground endpoint ([#133](https://github.com/reearth/reearth-backend/pull/133)) [`adeda4`](https://github.com/reearth/reearth-backend/commit/adeda4)

## 0.5.0 - 2022-02-24

### 🚀 Features

Expand Down
1 change: 1 addition & 0 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func initEcho(ctx context.Context, cfg *ServerConfig) *echo.Echo {
e.GET("/graphql", echo.WrapHandler(
playground.Handler("reearth-backend", "/api/graphql"),
))
log.Infof("gql: GraphQL Playground is available")
}

// init usecases
Expand Down
98 changes: 61 additions & 37 deletions internal/app/auth_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"context"
"crypto/sha256"
"encoding/json"
"errors"
"net/http"
"net/url"
"os"
"strconv"
"strings"

"github.com/caos/oidc/pkg/op"
"github.com/golang/gddo/httputil/header"
Expand All @@ -17,6 +17,7 @@ import (
"github.com/reearth/reearth-backend/internal/usecase/interactor"
"github.com/reearth/reearth-backend/internal/usecase/interfaces"
"github.com/reearth/reearth-backend/pkg/log"
"github.com/reearth/reearth-backend/pkg/user"
)

const (
Expand All @@ -29,16 +30,14 @@ const (
func authEndPoints(ctx context.Context, e *echo.Echo, r *echo.Group, cfg *ServerConfig) {
userUsecase := interactor.NewUser(cfg.Repos, cfg.Gateways, cfg.Config.SignupSecret, cfg.Config.Host_Web)

d := cfg.Config.AuthSrv.Domain
if d == "" {
d = cfg.Config.Host
}
domain, err := url.Parse(d)
if err != nil {
log.Panicf("auth: not valid auth domain: %s", d)
domain := cfg.Config.AuthServeDomainURL()
if domain == nil || domain.String() == "" {
log.Panicf("auth: not valid auth domain: %s", domain)
}
domain.Path = "/"

uidomain := cfg.Config.AuthServeUIDomainURL()

config := &op.Config{
Issuer: domain.String(),
CryptoKey: sha256.Sum256([]byte(cfg.Config.AuthSrv.Key)),
Expand Down Expand Up @@ -95,7 +94,7 @@ func authEndPoints(ctx context.Context, e *echo.Echo, r *echo.Group, cfg *Server
}

// Actual login endpoint
r.POST(loginEndpoint, login(ctx, cfg, storage, userUsecase))
r.POST(loginEndpoint, login(ctx, domain, uidomain, storage, userUsecase))

r.GET(logoutEndpoint, logout())

Expand Down Expand Up @@ -191,44 +190,68 @@ type loginForm struct {
AuthRequestID string `json:"id" form:"id"`
}

func login(ctx context.Context, cfg *ServerConfig, storage op.Storage, userUsecase interfaces.User) func(ctx echo.Context) error {
func login(ctx context.Context, url, uiurl *url.URL, storage op.Storage, userUsecase interfaces.User) func(ctx echo.Context) error {
return func(ec echo.Context) error {
request := new(loginForm)
err := ec.Bind(request)
if err != nil {
log.Errorln("auth: filed to parse login request")
return ec.Redirect(http.StatusFound, redirectURL(ec.Request().Referer(), !cfg.Debug, "", "Bad request!"))
return ec.Redirect(
http.StatusFound,
redirectURL(uiurl, "/login", "", "Bad request!"),
)
}

authRequest, err := storage.AuthRequestByID(ctx, request.AuthRequestID)
if err != nil {
if _, err := storage.AuthRequestByID(ctx, request.AuthRequestID); err != nil {
log.Errorf("auth: filed to parse login request: %s\n", err)
return ec.Redirect(http.StatusFound, redirectURL(ec.Request().Referer(), !cfg.Debug, "", "Bad request!"))
return ec.Redirect(
http.StatusFound,
redirectURL(uiurl, "/login", "", "Bad request!"),
)
}

if len(request.Email) == 0 || len(request.Password) == 0 {
log.Errorln("auth: one of credentials are not provided")
return ec.Redirect(http.StatusFound, redirectURL(authRequest.GetRedirectURI(), !cfg.Debug, request.AuthRequestID, "Bad request!"))
return ec.Redirect(
http.StatusFound,
redirectURL(uiurl, "/login", request.AuthRequestID, "Bad request!"),
)
}

// check user credentials from db
user, err := userUsecase.GetUserByCredentials(ctx, interfaces.GetUserByCredentials{
u, err := userUsecase.GetUserByCredentials(ctx, interfaces.GetUserByCredentials{
Email: request.Email,
Password: request.Password,
})
var auth *user.Auth
if err == nil {
auth = u.GetAuthByProvider(authProvider)
if auth == nil {
err = errors.New("The account is not signed up with Re:Earth")
}
}
if err != nil {
log.Errorf("auth: wrong credentials: %s\n", err)
return ec.Redirect(http.StatusFound, redirectURL(authRequest.GetRedirectURI(), !cfg.Debug, request.AuthRequestID, "Login failed; Invalid user ID or password."))
return ec.Redirect(
http.StatusFound,
redirectURL(uiurl, "/login", request.AuthRequestID, "Login failed; Invalid user ID or password."),
)
}

// Complete the auth request && set the subject
err = storage.(*interactor.AuthStorage).CompleteAuthRequest(ctx, request.AuthRequestID, user.GetAuthByProvider(authProvider).Sub)
err = storage.(*interactor.AuthStorage).CompleteAuthRequest(ctx, request.AuthRequestID, auth.Sub)
if err != nil {
log.Errorf("auth: failed to complete the auth request: %s\n", err)
return ec.Redirect(http.StatusFound, redirectURL(authRequest.GetRedirectURI(), !cfg.Debug, request.AuthRequestID, "Bad request!"))
return ec.Redirect(
http.StatusFound,
redirectURL(uiurl, "/login", request.AuthRequestID, "Bad request!"),
)
}

return ec.Redirect(http.StatusFound, "/authorize/callback?id="+request.AuthRequestID)
return ec.Redirect(
http.StatusFound,
redirectURL(url, "/authorize/callback", request.AuthRequestID, ""),
)
}
}

Expand All @@ -239,25 +262,26 @@ func logout() func(ec echo.Context) error {
}
}

func redirectURL(domain string, secure bool, requestID string, error string) string {
domain = strings.TrimPrefix(domain, "http://")
domain = strings.TrimPrefix(domain, "https://")

schema := "http"
if secure {
schema = "https"
func redirectURL(u *url.URL, p string, requestID, err string) string {
v := cloneURL(u)
if p != "" {
v.Path = p
}

u := url.URL{
Scheme: schema,
Host: domain,
Path: "login",
}

queryValues := u.Query()
queryValues.Set("id", requestID)
queryValues.Set("error", error)
u.RawQuery = queryValues.Encode()
if err != "" {
queryValues.Set("error", err)
}
v.RawQuery = queryValues.Encode()
return v.String()
}

return u.String()
func cloneURL(u *url.URL) *url.URL {
return &url.URL{
Scheme: u.Scheme,
Opaque: u.Opaque,
User: u.User,
Host: u.Host,
Path: u.Path,
}
}
75 changes: 67 additions & 8 deletions internal/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type AuthSrvConfig struct {
Dev bool
Disabled bool
Domain string
UIDomain string
Key string
DN *AuthSrvDNConfig
}
Expand All @@ -75,7 +76,7 @@ func (c AuthSrvConfig) AuthConfig(debug bool, host string) *AuthConfig {
}

var aud []string
if debug && host != "" && c.Domain != "" {
if debug && host != "" && c.Domain != "" && c.Domain != host {
aud = []string{host, c.Domain}
} else {
aud = []string{domain}
Expand Down Expand Up @@ -139,19 +140,35 @@ func ReadConfig(debug bool) (*Config, error) {
var c Config
err := envconfig.Process(configPrefix, &c)

// defailt values
// overwrite env vars
if !c.AuthSrv.Disabled && (c.Dev || c.AuthSrv.Dev || c.AuthSrv.Domain == "") {
if _, ok := os.LookupEnv(op.OidcDevMode); !ok {
_ = os.Setenv(op.OidcDevMode, "1")
}
}

// default values
if debug {
c.Dev = true
}
c.Host = addHTTPScheme(c.Host)
if c.Host_Web == "" {
c.Host_Web = c.Host
} else {
c.Host_Web = addHTTPScheme(c.Host_Web)
}

// overwrite env vars
if !c.AuthSrv.Disabled && (c.Dev || c.AuthSrv.Dev || c.AuthSrv.Domain == "") {
if _, ok := os.LookupEnv(op.OidcDevMode); !ok {
_ = os.Setenv(op.OidcDevMode, "1")
}
if c.AuthSrv.Domain == "" {
c.AuthSrv.Domain = c.Host
} else {
c.AuthSrv.Domain = addHTTPScheme(c.AuthSrv.Domain)
}
if c.Host_Web == "" {
c.Host_Web = c.Host
}
if c.AuthSrv.UIDomain == "" {
c.AuthSrv.UIDomain = c.Host_Web
} else {
c.AuthSrv.UIDomain = addHTTPScheme(c.AuthSrv.UIDomain)
}

return &c, err
Expand Down Expand Up @@ -242,3 +259,45 @@ func (ipd *AuthConfigs) Decode(value string) error {
*ipd = providers
return nil
}

func (c Config) HostURL() *url.URL {
u, err := url.Parse(c.Host)
if err != nil {
u = nil
}
return u
}

func (c Config) HostWebURL() *url.URL {
u, err := url.Parse(c.Host_Web)
if err != nil {
u = nil
}
return u
}

func (c Config) AuthServeDomainURL() *url.URL {
u, err := url.Parse(c.AuthSrv.Domain)
if err != nil {
u = nil
}
return u
}

func (c Config) AuthServeUIDomainURL() *url.URL {
u, err := url.Parse(c.AuthSrv.UIDomain)
if err != nil {
u = nil
}
return u
}

func addHTTPScheme(host string) string {
if host == "" {
return ""
}
if !strings.HasPrefix(host, "https://") && !strings.HasPrefix(host, "http://") {
host = "http://" + host
}
return host
}
6 changes: 6 additions & 0 deletions internal/app/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ func TestReadConfig(t *testing.T) {
assert.Equal(t, "hoge", cfg.Auth_ISS)
assert.Equal(t, "foo", cfg.Auth_AUD)
}

func Test_AddHTTPScheme(t *testing.T) {
assert.Equal(t, "http://a", addHTTPScheme("a"))
assert.Equal(t, "http://a", addHTTPScheme("http://a"))
assert.Equal(t, "https://a", addHTTPScheme("https://a"))
}

0 comments on commit 1aefdfc

Please sign in to comment.