Skip to content

Commit

Permalink
feat: add option to define callbackURL with -callbackurl and improve …
Browse files Browse the repository at this point in the history
…logging

- Removed hardcoded callbackURL and added a new option to define it using -callbackurl
- Improved logging format for better readability and alignment
  • Loading branch information
emma authored and strifel committed Jun 29, 2024
1 parent 05df4b2 commit 21fe180
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 49 deletions.
4 changes: 2 additions & 2 deletions get_code/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"time"
)

func GetCode() string {
srv := &http.Server{Addr: ":8070"}
func GetCode(callbackEndpoint string) string {
srv := &http.Server{Addr: callbackEndpoint + ":8070"}
code := ""

http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
Expand Down
7 changes: 4 additions & 3 deletions get_token/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"errors"
"io/ioutil"
"net/http"
"strconv"
nurl "net/url"
)

func Fetch(url string, id string, secret string, code string) (CodeResponse, error) {
func Fetch(url string, id string, secret string, code string, callbackEndpoint string) (CodeResponse, error) {
resp, err := http.PostForm(url, nurl.Values{
"client_id": {id},
"client_secret": {secret},
"redirect_uri": {"http://localhost:8070/callback"},
"redirect_uri": {"http://" + callbackEndpoint + ":8070/callback"},
"grant_type": {"authorization_code"},
"code": {code},
})
Expand All @@ -22,7 +23,7 @@ func Fetch(url string, id string, secret string, code string) (CodeResponse, err
}

if resp.StatusCode != 200 {
return CodeResponse{}, errors.New("status code not 200")
return CodeResponse{}, errors.New("HTTP " + strconv.Itoa(resp.StatusCode))
}

body, err := ioutil.ReadAll(resp.Body)
Expand Down
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
module github.com/strifel/openid-connect-debugger

go 1.17

require github.com/fatih/color v1.10.0

require (
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect
)
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
40 changes: 40 additions & 0 deletions logging/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package logging

import (
"fmt"
color "github.com/fatih/color"
"log"
"os"
)

var (
debugLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
infoLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
successLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
warnLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
errorLogger = log.New(os.Stderr, "", log.Ldate|log.Ltime)
)

func Debug(format string, v ...interface{}){
message := fmt.Sprintf(format, v...)
debugLogger.Println(fmt.Sprintf("%s %s", color.MagentaString("[DEBUG]"), message))
}

func Info(format string, v ...interface{}) {
message := fmt.Sprintf(format, v...)
infoLogger.Println(fmt.Sprintf("%s %s", color.CyanString("[INFO]"), message))
}
func Success(format string, v ...interface{}){
message := fmt.Sprintf(format, v...)
debugLogger.Println(fmt.Sprintf("%s %s", color.GreenString("[OK]"), message))
}

func Warn(format string, v ...interface{}) {
message := fmt.Sprintf(format, v...)
warnLogger.Println(fmt.Sprintf("%s %s", color.YellowString("[WARN]"), message))
}

func Error(format string, v ...interface{}) {
message := fmt.Sprintf(format, v...)
errorLogger.Println(fmt.Sprintf("%s %s", color.RedString("[ERROR]"), message))
}
91 changes: 49 additions & 42 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package main

import (
"flag"
"fmt"
"os/exec"

"github.com/strifel/openid-connect-debugger/flag_parsing"
getcode "github.com/strifel/openid-connect-debugger/get_code"
gettoken "github.com/strifel/openid-connect-debugger/get_token"
startconnection "github.com/strifel/openid-connect-debugger/start_connection"
userdata "github.com/strifel/openid-connect-debugger/user_data"
)


logging "github.com/strifel/openid-connect-debugger/logging")

func main() {
endpointUrl := flag.String("endpoint", "", "URL to instance")
Expand All @@ -20,96 +21,102 @@ func main() {
flag.Var(&scopes, "scope", "Specify scopes (e.g. -scope profile -scope openid)")
verbosity := flag.Int("verbosity", 0, "Verbosity level (0 to 3). 2 is verbose, 3 shows the access token")
macosOpen := flag.Bool("macosopen", false, "Open the browser on MacOS")

callbackEndpoint := flag.String("callbackurl", "", "Callback endpoint. Default http://localhost")

flag.Parse()

if *endpointUrl == "" {
fmt.Println("No endpoint URL given")
logging.Error("No endpoint URL given")
return
}

if *clientId == "" {
fmt.Println("No client ID given")
logging.Error("No client ID given")
return
}

if *secret == "" {
fmt.Println("No secret given")
logging.Error("No secret given")
return
}

if *callbackEndpoint == "" {
*callbackEndpoint = "localhost"
}

wellKnownURL := *endpointUrl + "/.well-known/openid-configuration"
fmt.Println("Starting connection to", wellKnownURL)
logging.Info("Starting connection to %s", wellKnownURL)
information, err := startconnection.Fetch(wellKnownURL)
if err != nil {
fmt.Println(err)
logging.Error("%v", err)
return
}

if *verbosity >= 2 {
fmt.Println("Issuer: ", information.Issuer)
fmt.Println("Authorization endpoint: ", information.AuthorizationEndpoint)
fmt.Println("Token endpoint: ", information.TokenEndpoint)
fmt.Println("Userinfo endpoint: ", information.UserinfoEndpoint)
logging.Debug("Issuer: %s", information.Issuer)
logging.Debug("Authorization endpoint: %s", information.AuthorizationEndpoint)
logging.Debug("Token endpoint: %s", information.TokenEndpoint)
logging.Debug("Userinfo endpoint: %s", information.UserinfoEndpoint)
}

fmt.Println("Read data")
logging.Info("Read data")

fmt.Println("Starting authorization phase")
fmt.Println("Please add http://localhost:8070/callback as valid redirect URI to your client")
authUrl := information.AuthorizationEndpoint + "?client_id=" + *clientId + "&response_type=code&scope=" + scopes.String() + "&redirect_uri=http://localhost:8070/callback"
fmt.Println("Then visit ", authUrl)
logging.Info("Starting authorization phase")
callbackURL := "http://" + *callbackEndpoint + ":8070/callback"
logging.Info("Please add " + callbackURL + " as valid redirect URI to your client")
authUrl := information.AuthorizationEndpoint + "?client_id=" + *clientId + "&response_type=code&scope=" + scopes.String() + "&redirect_uri=" + callbackURL
logging.Info("Then visit %s", authUrl)

if *macosOpen {
exec.Command("open", authUrl).Run()
}

code := getcode.GetCode()
code := getcode.GetCode(*callbackEndpoint)

if *verbosity >= 2 {
fmt.Println("Got code: ", code)
logging.Debug("Query Client code %s", code)
}

fmt.Println("Completed authorization phase")
logging.Success("Completed authorization phase")

fmt.Println("Starting token phase")
token, err := gettoken.Fetch(information.TokenEndpoint, *clientId, *secret, code)
logging.Info("Starting token phase")
token, err := gettoken.Fetch(information.TokenEndpoint, *clientId, *secret, code, *callbackEndpoint)
if err != nil {
fmt.Println(err)
logging.Error("%v", err)
return
}
if *verbosity >= 3 {
fmt.Println("Access token: ", token.AccessToken)
fmt.Println("Refresh token: ", token.RefreshToken)
logging.Debug("Access token:\n%s", token.AccessToken)
logging.Debug("Refresh token:\n%s", token.RefreshToken)
}
if *verbosity >= 2 {
fmt.Println("Session state: ", token.SessionState)
fmt.Println("Access token expires in: ", token.ExpiresIn)
fmt.Println("Refresh token expires in: ", token.RefreshExpiresIn)
fmt.Println("Not before policy: ", token.NotBeforePolicy)
fmt.Println("Scope: ", token.Scope)
logging.Debug("Session state: %s", token.SessionState)
logging.Debug("Access token TTL: %d", token.ExpiresIn)
logging.Debug("Refresh token TTL: %d", token.RefreshExpiresIn)
logging.Debug("Not before policy: %d", token.NotBeforePolicy)
logging.Debug("Scope: %s", token.Scope)
}

fmt.Println("Completed token phase")
logging.Success("Completed token phase")

fmt.Println("Starting userinfo phase")
logging.Info("Starting userinfo phase")
userinfo, rawUser, err := userdata.Fetch(information.UserinfoEndpoint, token.AccessToken)
if err != nil {
fmt.Println(err)
logging.Error("%v", err)
return
}
if *verbosity >= 1 {
fmt.Println("Username: ", userinfo.PreferredUsername)
fmt.Println("Email: ", userinfo.Email)
fmt.Println("Email verified: ", userinfo.EmailVerified)
fmt.Println("Name: ", userinfo.Name)
fmt.Println("Family name: ", userinfo.FamilyName)
fmt.Println("Given name: ", userinfo.GivenName)
fmt.Println("Sub: ", userinfo.Sub)
logging.Info("Username: %s", userinfo.PreferredUsername)
logging.Info("Email: %s", userinfo.Email)
logging.Info("Email verified: %t", userinfo.EmailVerified)
logging.Info("Name: %s", userinfo.Name)
logging.Info("Family name: %s", userinfo.FamilyName)
logging.Info("Given name: %s", userinfo.GivenName)
logging.Info("Sub: %s", userinfo.Sub)
}
if *verbosity >= 2 {
fmt.Println("Raw User Data: ", rawUser)
logging.Debug("Raw User Data: %s", rawUser)
}

fmt.Println("Completed userinfo phase")
logging.Success("Completed userinfo phase")
}
3 changes: 2 additions & 1 deletion start_connection/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"io/ioutil"
"net/http"
"strconv"
)

func Fetch(url string) (EndpointInformation, error) {
Expand All @@ -15,7 +16,7 @@ func Fetch(url string) (EndpointInformation, error) {
}

if resp.StatusCode != 200 {
return EndpointInformation{}, errors.New("status code not 200")
return EndpointInformation{}, errors.New("HTTP " + strconv.Itoa(resp.StatusCode))
}

body, err := ioutil.ReadAll(resp.Body)
Expand Down
3 changes: 2 additions & 1 deletion user_data/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"strconv"
)

func Fetch(url string, token string) (UserInfo, string, error) {
Expand All @@ -24,7 +25,7 @@ func Fetch(url string, token string) (UserInfo, string, error) {
}

if resp.StatusCode != 200 {
return UserInfo{}, "", errors.New("status code not 200")
return UserInfo{}, "", errors.New("HTTP " + strconv.Itoa(resp.StatusCode))
}

body, err := ioutil.ReadAll(resp.Body)
Expand Down

0 comments on commit 21fe180

Please sign in to comment.