Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for apps to create enrollments #26

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/nats-io/nats.go v1.36.0 h1:suEUPuWzTSse/XhESwqLxXGuj8vGRuPRoG7MoRN/qyU=
github.com/nats-io/nats.go v1.36.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE=
github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
Expand Down
5 changes: 5 additions & 0 deletions invopop/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ func (svc *AccessService) Workspace() *WorkspaceService {
func (svc *AccessService) Company() *WorkspaceService {
return svc.Workspace()
}

// Org returns the service for Access Organizations
func (svc *AccessService) Org() *OrgService {
return (*OrgService)(svc)
}
27 changes: 27 additions & 0 deletions invopop/access_enrollments.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"encoding/json"
"errors"
"path"

"github.com/invopop/gobl/uuid"
)

const (
Expand Down Expand Up @@ -42,6 +44,16 @@ type authorizeEnrollment struct {
ClientSecret string `json:"client_secret" title:"Client Secret" description:"The secret key of the application that is being enrolled." example:"YSKIfGaUrEdDFK_NPGO-Yj1oVDJcjV15N4hHbuAEg2c"`
}

// createEnrollment is used by apps to create an enrollment on behalf of
// an end user after choosing a workspace.
type createEnrollment struct {
ID string `param:"id" title:"ID" description:"UUIDv7 of the new enrollment to create." example:"01950020-daef-7d75-b1ba-33e7e392a658"`
OwnerID string `json:"owner_id" title:"Owner ID" description:"Workspace ID to associate with the enrollment."`
ClientID string `json:"client_id" title:"Client ID" description:"The ID of the application that is being enrolled." example:"XzhLPeXCi3GBVg"`
ClientSecret string `json:"client_secret" title:"Client Secret" description:"The secret key of the application that is being enrolled." example:"p2NWtVpuDxDYt41crWUBmQKaE4Mh92roDxp_8UKkIJY"`
Data json.RawMessage `json:"data" title:"Data" description:"Additional data associated with the enrollment." example:"{\"key\":\"value\"}"`
}

// UpdateEnrollment defines the request body for updating an enrollment.
type UpdateEnrollment struct {
Data json.RawMessage `param:"data" title:"Data" description:"Additional data associated with the enrollment." example:"{\"key\":\"value\"}"`
Expand Down Expand Up @@ -101,3 +113,18 @@ func (s *EnrollmentService) Update(ctx context.Context, req *UpdateEnrollment) (
e := new(Enrollment)
return e, s.client.post(ctx, p, req, e)
}

// Create will create an enrollment between a workspace and an application.
func (s *EnrollmentService) Create(ctx context.Context, ownerID string) (*Enrollment, error) {
enrollmentID := uuid.V7().String()
p := path.Join(accessBasePath, enrollmentPath, enrollmentID)

req := &createEnrollment{
ID: enrollmentID,
OwnerID: ownerID,
ClientID: s.client.clientID,
ClientSecret: s.client.clientSecret,
}
e := new(Enrollment)
return e, s.client.put(ctx, p, req, e)
}
35 changes: 35 additions & 0 deletions invopop/access_orgs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package invopop

import (
"context"
"path"
)

const (
orgsPath = "/orgs"
)

// OrgService is used to access the organizations associated with a user.
type OrgService service

// An Org is a top-level entity that groups together multiple workspaces
// and user positions.
type Org struct {
ID string `json:"id" title:"ID" description:"UUID of the organization." example:"347c5b04-cde2-11ed-afa1-0242ac120002"`
CreatedAt string `json:"created_at" title:"Created At" description:"The date and time the org was created." example:"2018-01-01T00:00:00.000Z"`
UpdatedAt string `json:"updated_at" title:"Updated At" description:"The date and time the org was last updated." example:"2018-01-01T00:00:00.000Z"`

Name string `json:"name" title:"Name" description:"The name of the organization." example:"My Organization"`
Domain string `json:"domain,omitempty" title:"Domain" description:"The domain of the organization." example:"myorg.com"`

// Optional list of workspaces
Workspaces []*Workspace `json:"workspaces,omitempty" title:"Workspaces" description:"Workspaces associated with the organization, if requested."`
}

// Fetch will attempt to retrieve the organizations associated with a user
// This method will only work with an oauth token
func (s *OrgService) Fetch(ctx context.Context) ([]*Org, error) {
p := path.Join(accessBasePath, orgsPath)
var orgs []*Org
return orgs, s.client.get(ctx, p, &orgs)
}
28 changes: 28 additions & 0 deletions pkg/echopop/echopop.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,34 @@ func AuthEnrollment(ic *invopop.Client) echo.MiddlewareFunc {

}

// AuthToken defines a middleware function that will check if the
// header contains an authentication token.
//
// If it does, the token will be included in the invopop client to be used
// to authenticate requests to the API. It is thought for endpoints where an
// oauth access token is required to access the API.
func AuthToken(ic *invopop.Client) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
tok := ""

// extract bearer auth token
ah := strings.Split(c.Request().Header.Get("Authorization"), "Bearer ")
if len(ah) == 2 && ah[1] != "" {
tok = ah[1]
}
if tok == "" {
return echo.NewHTTPError(http.StatusUnauthorized, "missing auth token")
}

c.Set(invopopClientKey, ic.SetAuthToken(tok))

return next(c)
}
}

}

// GetEnrollment retrieves the enrollment object from the context.
func GetEnrollment(c echo.Context) *invopop.Enrollment {
return c.Get(enrollmentKey).(*invopop.Enrollment)
Expand Down
Loading