Skip to content

Commit

Permalink
Working!
Browse files Browse the repository at this point in the history
  • Loading branch information
gbdubs committed Sep 11, 2023
1 parent a1a6abe commit 1807ff1
Show file tree
Hide file tree
Showing 23 changed files with 1,447 additions and 97 deletions.
3 changes: 2 additions & 1 deletion cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ func run(args []string) error {
AllowCredentials: true,
AllowedHeaders: []string{"Authorization", "Content-Type"},
// Enable Debugging for testing, consider disabling in production
Debug: true,
Debug: true,
AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
}).Handler(r)
} else {
handler = r
Expand Down
4 changes: 4 additions & 0 deletions cmd/server/pactasrv/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "pactasrv",
srcs = [
"conv_oapi_to_pacta.go",
"conv_pacta_to_oapi.go",
"error.go",
"initiative.go",
"pacta_version.go",
"pactasrv.go",
"user.go",
Expand Down
58 changes: 58 additions & 0 deletions cmd/server/pactasrv/conv_oapi_to_pacta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package pactasrv

import (
"fmt"
"regexp"

api "github.com/RMI/pacta/openapi/pacta"
"github.com/RMI/pacta/pacta"
)

var initiativeIDRegex = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)

func initiativeCreateToPACTA(i *api.InitiativeCreate) (*pacta.Initiative, error) {
if i == nil {
return nil, errorBadRequest("InitiativeCreate", "cannot be nil")
}
if !initiativeIDRegex.MatchString(i.Id) {
return nil, errorBadRequest("id", "must contain only alphanumeric characters, underscores, and dashes")
}
lang, err := pacta.ParseLanguage(string(i.Language))
if err != nil {
return nil, errorBadRequest("language", err.Error())
}
var pv *pacta.PACTAVersion
if i.PactaVersion != nil {
pv = &pacta.PACTAVersion{ID: pacta.PACTAVersionID(*i.PactaVersion)}
}
return &pacta.Initiative{
Affiliation: ifNil(i.Affiliation, ""),
ID: pacta.InitiativeID(i.Id),
InternalDescription: ifNil(i.InternalDescription, ""),
IsAcceptingNewMembers: ifNil(i.IsAcceptingNewMembers, false),
IsAcceptingNewPortfolios: ifNil(i.IsAcceptingNewPortfolios, false),
Language: lang,
Name: i.Name,
PACTAVersion: pv,
PublicDescription: ifNil(i.PublicDescription, ""),
RequiresInvitationToJoin: ifNil(i.RequiresInvitationToJoin, false),
}, nil
}

func pactaVersionCreateToPACTA(p *api.PactaVersionCreate) (*pacta.PACTAVersion, error) {
if p == nil {
return nil, fmt.Errorf("pactaVersionCreateToPACTA: nil pointer")
}
return &pacta.PACTAVersion{
Name: p.Name,
Digest: p.Digest,
Description: p.Description,
}, nil
}

func ifNil[T any](t *T, or T) T {
if t == nil {
return or
}
return *t
}
45 changes: 45 additions & 0 deletions cmd/server/pactasrv/conv_pacta_to_oapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package pactasrv

import (
"fmt"

api "github.com/RMI/pacta/openapi/pacta"
"github.com/RMI/pacta/pacta"
)

func initiativeToOAPI(i *pacta.Initiative) (*api.Initiative, error) {
if i == nil {
return nil, errorInternal(fmt.Errorf("initiativeToOAPI: can't convert nil pointer"))
}
return &api.Initiative{
Affiliation: i.Affiliation,
CreatedAt: i.CreatedAt,
Id: string(i.ID),
InternalDescription: i.InternalDescription,
IsAcceptingNewMembers: i.IsAcceptingNewMembers,
IsAcceptingNewPortfolios: i.IsAcceptingNewPortfolios,
Language: api.InitiativeLanguage(i.Language),
Name: i.Name,
PactaVersion: ptr(string(i.PACTAVersion.ID)),
PublicDescription: i.PublicDescription,
RequiresInvitationToJoin: i.RequiresInvitationToJoin,
}, nil
}

func pactaVersionToOAPI(pv *pacta.PACTAVersion) (*api.PactaVersion, error) {
if pv == nil {
return nil, errorInternal(fmt.Errorf("pactaVersionToOAPI: can't convert nil pointer"))
}
return &api.PactaVersion{
Id: string(pv.ID),
Name: pv.Name,
IsDefault: pv.IsDefault,
Digest: pv.Digest,
Description: pv.Description,
CreatedAt: pv.CreatedAt,
}, nil
}

func ptr[T any](t T) *T {
return &t
}
163 changes: 163 additions & 0 deletions cmd/server/pactasrv/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package pactasrv

import (
"fmt"

api "github.com/RMI/pacta/openapi/pacta"
)

type errBadRequest struct {
Field string
Message string
}

func (e *errBadRequest) Code() int32 {
return 400
}

func (e *errBadRequest) Error() string {
return fmt.Sprintf("bad request: field %q: %s", e.Field, e.Message)
}

func (e *errBadRequest) Is(target error) bool {
_, ok := target.(*errBadRequest)
return ok
}

func errorBadRequest(field string, message string) error {
return &errBadRequest{Field: field, Message: message}
}

type errUnauthorized struct {
Action string
Resource string
}

func (e *errUnauthorized) Code() int32 {
return 401
}

func (e *errUnauthorized) Error() string {
return fmt.Sprintf("unauthorized to %s %s", e.Action, e.Resource)
}

func (e *errUnauthorized) Is(target error) bool {
_, ok := target.(*errUnauthorized)
return ok
}

func errorUnauthorized(action string, resource string) error {
return &errUnauthorized{Action: action, Resource: resource}
}

type errForbidden struct {
Action string
Resource string
}

func (e *errForbidden) Code() int32 {
return 403
}

func (e *errForbidden) Error() string {
return fmt.Sprintf("user is not allowed to %s %s", e.Action, e.Resource)
}

func (e *errForbidden) Is(target error) bool {
_, ok := target.(*errForbidden)
return ok
}

func errorForbidden(action string, resource string) error {
return &errForbidden{Action: action, Resource: resource}
}

type errNotFound struct {
What string
With string
}

func (e *errNotFound) Code() int32 {
return 404
}

func (e *errNotFound) Error() string {
return fmt.Sprintf("not found: %s with %s", e.What, e.With)
}

func (e *errNotFound) Is(target error) bool {
_, ok := target.(*errNotFound)
return ok
}

func errorNotFound(what string, with string) error {
return &errNotFound{What: what, With: with}
}

type errInternal struct {
What string
}

func (e *errInternal) Code() int32 {
return 500
}

func (e *errInternal) Error() string {
return fmt.Sprintf("internal error: %s", e.What)
}

func (e *errInternal) Is(target error) bool {
_, ok := target.(*errInternal)
return ok
}

func errorInternal(err error) error {
return &errInternal{What: err.Error()}
}

type errNotImplemented struct {
What string
}

func (e *errNotImplemented) Code() int32 {
return 501
}

func (e *errNotImplemented) Error() string {
return fmt.Sprintf("not implemented: %s", e.What)
}

func (e *errNotImplemented) Is(target error) bool {
_, ok := target.(*errNotImplemented)
return ok
}

func errorNotImplemented(what string) error {
return &errNotImplemented{What: what}
}

func errToAPIError(err error) api.Error {
if e, ok := err.(*errBadRequest); ok {
return api.Error{Code: e.Code(), Message: e.Error()}
}
if e, ok := err.(*errUnauthorized); ok {
return api.Error{Code: e.Code(), Message: e.Error()}
}
if e, ok := err.(*errForbidden); ok {
return api.Error{Code: e.Code(), Message: e.Error()}
}
if e, ok := err.(*errNotFound); ok {
return api.Error{Code: e.Code(), Message: e.Error()}
}
if e, ok := err.(*errInternal); ok {
return api.Error{Code: e.Code(), Message: e.Error()}
}
if e, ok := err.(*errNotImplemented); ok {
return api.Error{Code: e.Code(), Message: e.Error()}
}
// TODO: log here for an unexpected error condition.
return api.Error{
Code: 500,
Message: "an unexpected error occurred",
}
}
Loading

0 comments on commit 1807ff1

Please sign in to comment.