-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,447 additions
and
97 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
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
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,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 | ||
} |
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,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 | ||
} |
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,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", | ||
} | ||
} |
Oops, something went wrong.