-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #101 from carverauto/99-portal-api
99 portal api
- Loading branch information
Showing
15 changed files
with
1,196 additions
and
78 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,46 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"github.com/carverauto/threadr/pkg/api/firebase" | ||
"github.com/carverauto/threadr/pkg/api/routes" | ||
"github.com/gofiber/fiber/v2" | ||
"github.com/joho/godotenv" | ||
"log" | ||
"time" | ||
) | ||
|
||
func main() { | ||
err := godotenv.Load() | ||
if err != nil { | ||
log.Println("Error loading .env file") | ||
} | ||
|
||
app := fiber.New( | ||
fiber.Config{ | ||
EnablePrintRoutes: true, | ||
}, | ||
) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
||
FirebaseApp, err := firebase.SetupFirebaseApp(ctx) | ||
if err != nil { | ||
log.Println("Error initializing Firebase App:", err) | ||
return | ||
} | ||
|
||
// Group for routes that require tenant and role verification | ||
secure := app.Group("/secure") | ||
routes.SetupSecureRoutes(secure, FirebaseApp) | ||
|
||
// General and admin routes setup | ||
routes.SetupRoutes(app, FirebaseApp) | ||
|
||
fErr := app.Listen(":3001") | ||
if fErr != nil { | ||
log.Println("Error starting the server:", fErr) | ||
return | ||
} | ||
} |
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,91 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
) | ||
|
||
// GetClaims gets custom claims for a user | ||
func GetClaims(apiURL, apiKey, userID string) error { | ||
url := fmt.Sprintf(apiURL, userID) | ||
log.Println("URL:", url) | ||
|
||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("API Key: %s\n", apiKey) | ||
|
||
req.Header.Set("Content-Type", "application/json") | ||
req.Header.Set("X-API-Key", apiKey) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
|
||
// print the body | ||
buf := new(bytes.Buffer) | ||
_, err = buf.ReadFrom(resp.Body) | ||
if err != nil { | ||
return err | ||
} | ||
body := buf.String() | ||
fmt.Println(body) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return fmt.Errorf("failed to get claims, server responded with status code: %d", resp.StatusCode) | ||
} | ||
|
||
fmt.Println("Custom claims retrieved successfully.") | ||
return nil | ||
} | ||
|
||
// SendClaimsUpdate sends a POST request to set custom claims for a user | ||
func SendClaimsUpdate(apiURL, apiKey, userID string, userClaims map[string]string) error { | ||
claims := Claims{ | ||
UserID: userID, | ||
Claims: userClaims, | ||
} | ||
|
||
claimsJSON, err := json.Marshal(claims) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(claimsJSON)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
req.Header.Set("Content-Type", "application/json") | ||
req.Header.Set("X-API-Key", apiKey) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
|
||
// print the body | ||
buf := new(bytes.Buffer) | ||
_, err = buf.ReadFrom(resp.Body) | ||
if err != nil { | ||
return err | ||
} | ||
body := buf.String() | ||
fmt.Println(body) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return fmt.Errorf("failed to set claims, server responded with status code: %d", resp.StatusCode) | ||
} | ||
|
||
return nil | ||
} |
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,24 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
firebase "firebase.google.com/go" | ||
"fmt" | ||
threadrFirebase "github.com/carverauto/threadr/pkg/api/firebase" | ||
"log" | ||
"time" | ||
) | ||
|
||
// firebaseAuth is a function that logs in a user | ||
func firebaseAuth() (*firebase.App, error) { | ||
fmt.Println("Logging in user...") | ||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
||
FirebaseApp, err := threadrFirebase.SetupFirebaseApp(ctx) | ||
if err != nil { | ||
log.Println("Error initializing Firebase App:", err) | ||
return nil, err | ||
} | ||
return FirebaseApp, nil | ||
} |
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,53 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os" | ||
) | ||
|
||
type Claims struct { | ||
UserID string `json:"userId"` | ||
Claims map[string]string `json:"claims"` | ||
} | ||
|
||
const ( | ||
setClaimsURL = "http://localhost:3001/admin/set-claims" | ||
getClaimsURL = "http://localhost:3001/admin/get-claims/%s" | ||
secureEndpoint = "http://localhost:3001/secure/%s" | ||
) | ||
|
||
func main() { | ||
apiKey := os.Getenv("ADMIN_API_KEY") | ||
if apiKey == "" { | ||
fmt.Println("ADMIN_API_KEY is not set.") | ||
return | ||
} | ||
|
||
// Define the user and claims you want to set | ||
userID := os.Getenv("FIREBASE_USER_ID") | ||
userClaims := map[string]string{ | ||
"role": "admin", | ||
"tenantId": "threadr", | ||
} | ||
|
||
err := SendClaimsUpdate(setClaimsURL, apiKey, userID, userClaims) | ||
if err != nil { | ||
fmt.Println("Error setting custom claims:", err) | ||
return | ||
} | ||
|
||
log.Printf("Getting custom claims for user: %s\n", userID) | ||
|
||
err = GetClaims(getClaimsURL, apiKey, userID) | ||
if err != nil { | ||
fmt.Println("Error getting custom claims:", err) | ||
return | ||
} | ||
|
||
// Test the secure endpoint that requires tenant ID in the URL | ||
log.Printf("Accessing secure tenant endpoint for tenant: %s\n", userClaims["tenantId"]) | ||
if err := AccessSecureEndpoint(fmt.Sprintf(secureEndpoint, userClaims["tenantId"]), apiKey); err != nil { | ||
fmt.Println("Error accessing secure endpoint:", 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,43 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
) | ||
|
||
// AccessSecureEndpoint accesses a secure endpoint that requires tenant-level security | ||
func AccessSecureEndpoint(url, apiKey string) error { | ||
log.Println("URL:", url) | ||
|
||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
req.Header.Set("Authorization", "Bearer <Token>") // This should be your Firebase token | ||
req.Header.Set("X-API-Key", apiKey) | ||
|
||
client := &http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
|
||
buf := new(bytes.Buffer) | ||
_, err = buf.ReadFrom(resp.Body) | ||
if err != nil { | ||
return err | ||
} | ||
body := buf.String() | ||
fmt.Println(body) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return fmt.Errorf("failed to access secure endpoint, server responded with status code: %d", resp.StatusCode) | ||
} | ||
|
||
fmt.Println("Secure endpoint accessed successfully.") | ||
return nil | ||
} |
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,63 @@ | ||
module github.com/carverauto/threadr | ||
|
||
go 1.21.3 | ||
|
||
require ( | ||
firebase.google.com/go v3.13.0+incompatible | ||
firebase.google.com/go/v4 v4.14.0 | ||
github.com/gofiber/fiber/v2 v2.52.4 | ||
github.com/joho/godotenv v1.5.1 | ||
github.com/sacsand/gofiber-firebaseauth v1.4.3 | ||
google.golang.org/api v0.176.0 | ||
) | ||
|
||
require ( | ||
cloud.google.com/go v0.112.1 // indirect | ||
cloud.google.com/go/auth v0.2.2 // indirect | ||
cloud.google.com/go/auth/oauth2adapt v0.2.1 // indirect | ||
cloud.google.com/go/compute/metadata v0.3.0 // indirect | ||
cloud.google.com/go/firestore v1.15.0 // indirect | ||
cloud.google.com/go/iam v1.1.7 // indirect | ||
cloud.google.com/go/longrunning v0.5.5 // indirect | ||
cloud.google.com/go/storage v1.40.0 // indirect | ||
github.com/MicahParks/keyfunc v1.9.0 // indirect | ||
github.com/andybalholm/brotli v1.0.5 // indirect | ||
github.com/felixge/httpsnoop v1.0.4 // indirect | ||
github.com/go-logr/logr v1.4.1 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||
github.com/golang/protobuf v1.5.4 // indirect | ||
github.com/google/s2a-go v0.1.7 // indirect | ||
github.com/google/uuid v1.6.0 // indirect | ||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect | ||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect | ||
github.com/klauspost/compress v1.17.0 // indirect | ||
github.com/mattn/go-colorable v0.1.13 // indirect | ||
github.com/mattn/go-isatty v0.0.20 // indirect | ||
github.com/mattn/go-runewidth v0.0.15 // indirect | ||
github.com/rivo/uniseg v0.2.0 // indirect | ||
github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
github.com/valyala/fasthttp v1.51.0 // indirect | ||
github.com/valyala/tcplisten v1.0.0 // indirect | ||
go.opencensus.io v0.24.0 // indirect | ||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect | ||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect | ||
go.opentelemetry.io/otel v1.24.0 // indirect | ||
go.opentelemetry.io/otel/metric v1.24.0 // indirect | ||
go.opentelemetry.io/otel/trace v1.24.0 // indirect | ||
golang.org/x/crypto v0.22.0 // indirect | ||
golang.org/x/net v0.24.0 // indirect | ||
golang.org/x/oauth2 v0.19.0 // indirect | ||
golang.org/x/sync v0.6.0 // indirect | ||
golang.org/x/sys v0.19.0 // indirect | ||
golang.org/x/text v0.14.0 // indirect | ||
golang.org/x/time v0.5.0 // indirect | ||
google.golang.org/appengine v1.6.8 // indirect | ||
google.golang.org/appengine/v2 v2.0.2 // indirect | ||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect | ||
google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect | ||
google.golang.org/grpc v1.63.2 // indirect | ||
google.golang.org/protobuf v1.33.0 // indirect | ||
) |
Oops, something went wrong.