Skip to content

Commit 20e782f

Browse files
authored
Merge pull request #2 from remove158/fix/query-params-conserved
Fix query params conserved
2 parents 78c1af2 + 4f2a89e commit 20e782f

4 files changed

Lines changed: 88 additions & 5 deletions

File tree

cmd/handlers/auth.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package handlers
33
import (
44
"fmt"
55
"net/http"
6+
"net/url"
67

78
"github.com/gin-gonic/gin"
89
"github.com/google/wire"
@@ -37,6 +38,11 @@ func (h *AuthHandler) GetLogin(ctx *gin.Context) {
3738
return
3839
}
3940

41+
if _, err := url.Parse(request.Service); err != nil {
42+
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
43+
return
44+
}
45+
4046
ctx.HTML(http.StatusOK, "index.html", gin.H{
4147
"service": request.Service,
4248
})
@@ -50,7 +56,13 @@ func (h *AuthHandler) PostLogin(ctx *gin.Context) {
5056
}
5157
user := generateUserResponse(request)
5258
ticket := h.authService.PostLogin(user)
53-
ctx.Redirect(http.StatusFound, generatePath(request.Service, ticket))
59+
60+
redirectURL, err := h.authService.GeneratePath(request.Service, ticket)
61+
if err != nil {
62+
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
63+
return
64+
}
65+
ctx.Redirect(http.StatusFound, redirectURL)
5466
}
5567

5668
func generateUserResponse(request models.PostLoginRequest) models.UserResponse {
@@ -72,10 +84,6 @@ func generateUserResponse(request models.PostLoginRequest) models.UserResponse {
7284
}
7385
}
7486

75-
func generatePath(service string, ticket string) string {
76-
return fmt.Sprintf("%s?ticket=%s", service, ticket)
77-
}
78-
7987
func (h *AuthHandler) ServiceValidation(ctx *gin.Context) {
8088
var request models.ServiceValidateRequest
8189
if err := ctx.ShouldBindHeader(&request); err != nil {

internal/services/auth.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package services
22

33
import (
44
"fmt"
5+
"net/url"
56

67
"github.com/google/uuid"
78
"github.com/google/wire"
@@ -20,6 +21,7 @@ type AppSecret struct {
2021
type IAuthService interface {
2122
PostLogin(user models.UserResponse) string
2223
ServiceValidation(models.ServiceValidateRequest) (models.UserResponse, error)
24+
GeneratePath(service string, ticket string) (result string, err error)
2325
}
2426

2527
type AuthService struct {
@@ -54,3 +56,18 @@ func (h *AuthService) ServiceValidation(request models.ServiceValidateRequest) (
5456
}
5557
return user, nil
5658
}
59+
60+
func (h *AuthService) GeneratePath(service string, ticket string) (string, error) {
61+
u, err := url.Parse(service)
62+
63+
if err != nil {
64+
return "", err
65+
}
66+
67+
values := u.Query()
68+
values.Add("ticket", ticket)
69+
70+
u.RawQuery = values.Encode()
71+
72+
return u.String(), nil
73+
}

internal/services/auth_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package services_test
22

33
import (
4+
"net/url"
45
"testing"
56

67
"github.com/remove158/chula-sso/cmd/models"
@@ -89,3 +90,45 @@ func (s *AuthServiceTest) TestServiceValidationFailOnTicketInvalid() {
8990
s.Error(err)
9091
s.Empty(result)
9192
}
93+
94+
func (s *AuthServiceTest) TestGenerateRedirectURLSuccess() {
95+
service := "https://www.google.com"
96+
ticket := "this-is-a-ticket"
97+
result, err := s.authService.GeneratePath(service, ticket)
98+
s.NoError(err)
99+
100+
resultURL, err := url.Parse(result)
101+
s.NoError(err)
102+
expected, err := url.Parse("https://www.google.com?ticket=this-is-a-ticket")
103+
s.NoError(err)
104+
105+
s.Equal(resultURL.Host, expected.Host)
106+
s.Equal(resultURL.Path, expected.Path)
107+
s.Equal(resultURL.RawQuery, expected.RawQuery)
108+
s.Equal(resultURL.Scheme, expected.Scheme)
109+
}
110+
111+
func (s *AuthServiceTest) TestGenerateRedirectURLSuccessWithConservedURL() {
112+
service := "https://www.google.com/?redirect=%2Fhome&test=1"
113+
ticket := "this-is-a-ticket"
114+
result, err := s.authService.GeneratePath(service, ticket)
115+
s.NoError(err)
116+
117+
resultURL, err := url.Parse(result)
118+
s.NoError(err)
119+
expected, err := url.Parse("https://www.google.com/?redirect=%2Fhome&test=1&ticket=this-is-a-ticket")
120+
s.NoError(err)
121+
122+
s.Equal(resultURL.Host, expected.Host)
123+
s.Equal(resultURL.Path, expected.Path)
124+
s.Equal(resultURL.RawQuery, expected.RawQuery)
125+
s.Equal(resultURL.Scheme, expected.Scheme)
126+
}
127+
128+
func (s *AuthServiceTest) TestGenerateRedirectURLFailWithCantPraseURLService() {
129+
service := "postgres://user:abc{DEf1=ghi@example.com:5432/db?sslmode=require"
130+
ticket := "this-is-a-ticket"
131+
result, err := s.authService.GeneratePath(service, ticket)
132+
s.Error(err)
133+
s.Empty(result)
134+
}

internal/services/mocks/auth.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)