Skip to content

Commit

Permalink
Fix conflict post refactoring (#760)
Browse files Browse the repository at this point in the history
* Handle multiple registered directories in BFF

* Version bump to v1.5.0

* Certman refactor and automated reissuance (#753)

Co-authored-by: kbelita <[email protected]>
Co-authored-by: Daniel Sollis <[email protected]>

* sc-8837 Extend Background Color to bottom of Overview page (#754)

* sc-8408 Add min/max to date of incorporation field (#743)

* Handle multiple registered directories in BFF

* sc-8408 Add min/max to date of incorporation field

Co-authored-by: Benjamin Bengfort <[email protected]>

* sc-8837 Extend Background Color to bottom of Overview page

Co-authored-by: Benjamin Bengfort <[email protected]>
Co-authored-by: Cletus Razakou <[email protected]>

* adds slack notifications to Github Actions container build yaml (#755)

Co-authored-by: Cletus Razakou <[email protected]>

* Allow multiple DNS names in certificate issuance (#701)

Co-authored-by: Benjamin Bengfort <[email protected]>

* Add baggage to CORS allowed headers

* BFF test cleanup (#706)

* BFF string constants (#708)

* Add VASP timestamps to overview response (#740)

* version bump v1.5.0-rc.22

* add VASP timestamps to overview response

* Emit unpopulated registration form fields (#741)

* sc-8837 Extend Background Color to bottom of Overview page (#754)

* sc-8408 Add min/max to date of incorporation field (#743)

* Handle multiple registered directories in BFF

* sc-8408 Add min/max to date of incorporation field

Co-authored-by: Benjamin Bengfort <[email protected]>

* sc-8837 Extend Background Color to bottom of Overview page

Co-authored-by: Benjamin Bengfort <[email protected]>
Co-authored-by: Cletus Razakou <[email protected]>

* fix models merge conflicts

Co-authored-by: Benjamin Bengfort <[email protected]>
Co-authored-by: Patrick Deziel <[email protected]>
Co-authored-by: kbelita <[email protected]>
Co-authored-by: Daniel Sollis <[email protected]>
Co-authored-by: elysee15 <[email protected]>
Co-authored-by: Rebecca Bilbro <[email protected]>
  • Loading branch information
7 people authored Sep 6, 2022
1 parent b457fa8 commit 271d164
Show file tree
Hide file tree
Showing 26 changed files with 312 additions and 320 deletions.
19 changes: 11 additions & 8 deletions pkg/bff/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/trisacrypto/directory/pkg/bff/api/v1"
"github.com/trisacrypto/directory/pkg/bff/auth"
"github.com/trisacrypto/directory/pkg/bff/config"
records "github.com/trisacrypto/directory/pkg/bff/db/models/v1"
"github.com/trisacrypto/directory/pkg/gds/admin/v2"
"github.com/trisacrypto/directory/pkg/gds/models/v1"
Expand All @@ -27,9 +28,9 @@ func (s *Server) GetCertificates(ctx context.Context, testnetID, mainnetID strin
rpc := func(ctx context.Context, client admin.DirectoryAdministrationClient, network string) (rep interface{}, err error) {
var vaspID string
switch network {
case testnet:
case config.TestNet:
vaspID = testnetID
case mainnet:
case config.MainNet:
vaspID = mainnetID
default:
return nil, fmt.Errorf("unknown network: %s", network)
Expand Down Expand Up @@ -134,11 +135,13 @@ func (s *Server) Certificates(c *gin.Context) {
}

const (
testnetName = "TestNet"
mainnetName = "MainNet"
supportEmail = "[email protected]"
StartRegistration = "Start the registration and verification process for your organization to receive an X.509 Identity Certificate and become a trusted member of the TRISA network."
CompleteRegistration = "Complete the registration process and verification process for your organization to receive an X.509 Identity Certificate and become a trusted member of the TRISA network."
SubmitTestnet = "Review and submit your TestNet registration."
SubmitMainnet = "Review and submit your MainNet registration."
SubmitTestnet = "Review and submit your " + testnetName + " registration."
SubmitMainnet = "Review and submit your " + mainnetName + " registration."
VerifyEmails = "Your organization's %s registration has been submitted and verification emails have been sent to the contacts specified in the form. Contacts and email addresses must be verified as the first step in the approval process. Please request that contacts verify their email addresses promptly so that the TRISA Validation Team can proceed with the validation process. Please contact TRISA support at " + supportEmail + " if contacts have not received the verification email and link."
RegistrationPending = "Your organization's %s registration has been received and is pending approval. The TRISA Validation Team will notify you about the outcome."
RegistrationRejected = "Your organization's %s registration has been rejected by the TRISA Validation Team. This means your organization is not a verified member of the TRISA network and cannot communicate with other members. Please contact TRISA support at " + supportEmail + " for additional details and next steps."
Expand All @@ -156,9 +159,9 @@ func (s *Server) GetVASPs(ctx context.Context, testnetID, mainnetID string) (tes
rpc := func(ctx context.Context, client admin.DirectoryAdministrationClient, network string) (rep interface{}, err error) {
var vaspID string
switch network {
case testnet:
case config.TestNet:
vaspID = testnetID
case mainnet:
case config.MainNet:
vaspID = mainnetID
default:
return nil, fmt.Errorf("unknown network: %s", network)
Expand Down Expand Up @@ -351,7 +354,7 @@ func (s *Server) Attention(c *gin.Context) {

// Get attention messages relating to certificates
var testnetMsg *api.AttentionMessage
if testnetMsg, err = registrationMessage(testnetVASP, "TestNet"); err != nil {
if testnetMsg, err = registrationMessage(testnetVASP, testnetName); err != nil {
log.Error().Err(err).Msg("could not get testnet certificate attention message")
c.JSON(http.StatusInternalServerError, api.ErrorResponse(err))
return
Expand All @@ -361,7 +364,7 @@ func (s *Server) Attention(c *gin.Context) {
}

var mainnetMsg *api.AttentionMessage
if mainnetMsg, err = registrationMessage(mainnetVASP, "MainNet"); err != nil {
if mainnetMsg, err = registrationMessage(mainnetVASP, mainnetName); err != nil {
log.Error().Err(err).Msg("could not get mainnet certificate attention message")
c.JSON(http.StatusInternalServerError, api.ErrorResponse(err))
return
Expand Down
24 changes: 12 additions & 12 deletions pkg/bff/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ func (s *bffTestSuite) TestCertificates() {

// Endpoint must be authenticated
_, err := s.client.Certificates(context.TODO())
require.EqualError(err, "[401] this endpoint requires authentication", "expected error when user is not authenticated")
s.requireError(err, http.StatusUnauthorized, "this endpoint requires authentication", "expected error when user is not authenticated")

// Endpoint requires the read:vasp permission
require.NoError(s.SetClientCredentials(claims), "could not create token with incorrect permissions")
_, err = s.client.Certificates(context.TODO())
require.EqualError(err, "[401] user does not have permission to perform this operation", "expected error when user is not authorized")
s.requireError(err, http.StatusUnauthorized, "user does not have permission to perform this operation", "expected error when user is not authorized")

// Set valid credentials for the remainder of the tests
claims.Permissions = []string{"read:vasp"}
Expand Down Expand Up @@ -146,24 +146,24 @@ func (s *bffTestSuite) TestAttention() {

// Endpoint must be authenticated
_, err = s.client.Attention(context.TODO())
require.EqualError(err, "[401] this endpoint requires authentication", "expected error when user is not authenticated")
s.requireError(err, http.StatusUnauthorized, "this endpoint requires authentication", "expected error when user is not authenticated")

// Endpoint requires the read:vasp permission
require.NoError(s.SetClientCredentials(claims), "could not create token with incorrect permissions")
_, err = s.client.Attention(context.TODO())
require.EqualError(err, "[401] user does not have permission to perform this operation", "expected error when user is not authorized")
s.requireError(err, http.StatusUnauthorized, "user does not have permission to perform this operation", "expected error when user is not authorized")

// Claims must have an organization ID
claims.Permissions = []string{"read:vasp"}
require.NoError(s.SetClientCredentials(claims), "could not create token with correct permissions")
_, err = s.client.Attention(context.TODO())
require.EqualError(err, "[401] missing claims info, try logging out and logging back in", "expected error when user claims does not have an orgid")
s.requireError(err, http.StatusUnauthorized, "missing claims info, try logging out and logging back in", "expected error when user claims does not have an orgid")

// Create valid claims but no record in the database - should not panic and should return an error
claims.OrgID = "2295c698-afdc-4aaf-9443-85a4515217e3"
require.NoError(s.SetClientCredentials(claims), "could not create token with valid claims")
_, err = s.client.Attention(context.TODO())
require.EqualError(err, "[401] no organization found, try logging out and logging back in", "expected error when claims are valid but no organization is in the database")
s.requireError(err, http.StatusUnauthorized, "no organization found, try logging out and logging back in", "expected error when claims are valid but no organization is in the database")

// Start registration message should be returned when there is no registration form
claims.OrgID = org.Id
Expand Down Expand Up @@ -243,15 +243,15 @@ func (s *bffTestSuite) TestAttention() {
require.NoError(s.SetClientCredentials(claims), "could not create token with valid claims")
s.testnet.admin.UseError(mock.RetrieveVASPEP, http.StatusNotFound, "could not find VASP in database")
_, err = s.client.Attention(context.TODO())
require.EqualError(err, "[500] 404 Not Found", "expected error when VASP does not exist in testnet")
s.requireError(err, http.StatusInternalServerError, "404 Not Found", "expected error when VASP does not exist in testnet")

// Test an error is returned when VASP does not exist in mainnet
claims.VASPs["testnet"] = ""
claims.VASPs["mainnet"] = "alice1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1"
require.NoError(s.SetClientCredentials(claims), "could not create token with valid claims")
s.mainnet.admin.UseError(mock.RetrieveVASPEP, http.StatusNotFound, "could not find VASP in database")
_, err = s.client.Attention(context.TODO())
require.EqualError(err, "[500] 404 Not Found", "expected error when VASP does not exist in mainnet")
s.requireError(err, http.StatusInternalServerError, "404 Not Found", "expected error when VASP does not exist in mainnet")

// Verify emails message should be returned when the VASP has been submitted but
// emails are not yet verified
Expand Down Expand Up @@ -430,24 +430,24 @@ func (s *bffTestSuite) TestRegistrationStatus() {

// Endpoint must be authenticated
_, err = s.client.RegistrationStatus(context.TODO())
require.EqualError(err, "[401] this endpoint requires authentication", "expected error when user is not authenticated")
s.requireError(err, http.StatusUnauthorized, "this endpoint requires authentication", "expected error when user is not authenticated")

// Endpoint requires the read:vasp permission
require.NoError(s.SetClientCredentials(claims), "could not create token with incorrect permissions")
_, err = s.client.RegistrationStatus(context.TODO())
require.EqualError(err, "[401] user does not have permission to perform this operation", "expected error when user is not authorized")
s.requireError(err, http.StatusUnauthorized, "user does not have permission to perform this operation", "expected error when user is not authorized")

// Claims must have an organization ID
claims.Permissions = []string{"read:vasp"}
require.NoError(s.SetClientCredentials(claims), "could not create token with correct permissions")
_, err = s.client.RegistrationStatus(context.TODO())
require.EqualError(err, "[401] missing claims info, try logging out and logging back in", "expected error when user claims does not have an orgid")
s.requireError(err, http.StatusUnauthorized, "missing claims info, try logging out and logging back in", "expected error when user claims does not have an orgid")

// Create valid claims but no record in the database - should not panic and should return an error
claims.OrgID = "2295c698-afdc-4aaf-9443-85a4515217e3"
require.NoError(s.SetClientCredentials(claims), "could not create token with valid claims")
_, err = s.client.RegistrationStatus(context.TODO())
require.EqualError(err, "[401] no organization found, try logging out and logging back in", "expected error when claims are valid but no organization is in the database")
s.requireError(err, http.StatusUnauthorized, "no organization found, try logging out and logging back in", "expected error when claims are valid but no organization is in the database")

// Should return an empty response when there are no directory records
claims.OrgID = org.Id
Expand Down
17 changes: 9 additions & 8 deletions pkg/bff/announcements_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math/rand"
"net/http"
"time"

"github.com/trisacrypto/directory/pkg/bff/auth/authtest"
Expand Down Expand Up @@ -32,12 +33,12 @@ func (s *bffTestSuite) TestAnnouncements() {

// Endpoint must be authenticated
_, err := s.client.Announcements(context.TODO())
require.EqualError(err, "[401] this endpoint requires authentication", "expected error when user is not authenticated")
s.requireError(err, http.StatusUnauthorized, "this endpoint requires authentication", "expected error when user is not authenticated")

// Endpoint requires the read:vasp permission
require.NoError(s.SetClientCredentials(claims), "could not create token with incorrect permissions")
_, err = s.client.Announcements(context.TODO())
require.EqualError(err, "[401] user does not have permission to perform this operation", "expected error when user is not authorized")
s.requireError(err, http.StatusUnauthorized, "user does not have permission to perform this operation", "expected error when user is not authorized")

// Set valid credentials for the remainder of the tests
claims.Permissions = []string{"read:vasp"}
Expand Down Expand Up @@ -110,17 +111,17 @@ func (s *bffTestSuite) TestMakeAnnouncement() {

// Endpoint requires CSRF protection
err := s.client.MakeAnnouncement(context.TODO(), post)
require.EqualError(err, "[403] csrf verification failed for request", "expected error when request is not CSRF protected")
s.requireError(err, http.StatusForbidden, "csrf verification failed for request", "expected error when request is not CSRF protected")
require.NoError(s.SetClientCSRFProtection(), "could not set csrf protection on client")

// Endpoint must be authenticated
err = s.client.MakeAnnouncement(context.TODO(), post)
require.EqualError(err, "[401] this endpoint requires authentication", "expected error when user is not authenticated")
s.requireError(err, http.StatusUnauthorized, "this endpoint requires authentication", "expected error when user is not authenticated")

// Endpoint requires the read:vasp permission
require.NoError(s.SetClientCredentials(claims), "could not create token with incorrect permissions")
err = s.client.MakeAnnouncement(context.TODO(), post)
require.EqualError(err, "[401] user does not have permission to perform this operation", "expected error when user is not authorized")
s.requireError(err, http.StatusUnauthorized, "user does not have permission to perform this operation", "expected error when user is not authorized")

// Set valid credentials for the remainder of the tests
claims.Permissions = []string{"create:announcements"}
Expand Down Expand Up @@ -156,18 +157,18 @@ func (s *bffTestSuite) TestMakeAnnouncement() {
// Post should not have post_date set
post.PostDate = "2022-07-04"
err = s.client.MakeAnnouncement(context.TODO(), post)
require.EqualError(err, "[400] cannot set the post_date or author fields on the post", "expected post date required empty")
s.requireError(err, http.StatusBadRequest, "cannot set the post_date or author fields on the post", "expected post date required empty")

// Post should not have author set
post.PostDate = ""
post.Author = "James Jillian"
err = s.client.MakeAnnouncement(context.TODO(), post)
require.EqualError(err, "[400] cannot set the post_date or author fields on the post", "expected post date required empty")
s.requireError(err, http.StatusBadRequest, "cannot set the post_date or author fields on the post", "expected post date required empty")

// Require email in claims to make announcement
post.Author = ""
claims.Email = ""
require.NoError(s.SetClientCredentials(claims), "could not create token from valid credentials without email")
err = s.client.MakeAnnouncement(context.TODO(), post)
require.EqualError(err, "[400] user claims are not correctly configured", "expected post date required empty")
s.requireError(err, http.StatusBadRequest, "user claims are not correctly configured", "expected post date required empty")
}
3 changes: 3 additions & 0 deletions pkg/bff/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ type MemberDetails struct {
ID string `json:"id"`
Status string `json:"status"`
CountryCode string `json:"country_code"`
FirstListed string `json:"first_listed"`
VerifiedOn string `json:"verified_on"`
LastUpdated string `json:"last_updated"`
Certificate map[string]interface{} `json:"certificate"`
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/bff/api/v1/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/trisacrypto/directory/pkg/bff/config"
)

var (
Expand All @@ -16,7 +17,7 @@ var (
)

var (
ErrNetworkRequired = errors.New("request requires a valid network (mainnet or testnet)")
ErrNetworkRequired = fmt.Errorf("request requires a valid network (%s or %s)", config.TestNet, config.MainNet)
ErrInvalidCredentials = errors.New("auth0 credentials are missing or invalid")
ErrExpiredCredentials = errors.New("auth0 credentials have expired")
ErrPathRequired = errors.New("local credentials requires a path to the stored json credential")
Expand Down
4 changes: 2 additions & 2 deletions pkg/bff/auth/authtest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ func (s *Server) NewToken(permissions ...string) (tks string, err error) {
Email: Email,
OrgID: OrgID,
VASPs: map[string]string{
"testnet": TestNetVASP,
"mainnet": MainNetVASP,
config.TestNet: TestNetVASP,
config.MainNet: MainNetVASP,
},
Scope: Scope,
Permissions: permissions,
Expand Down
5 changes: 5 additions & 0 deletions pkg/bff/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ import (
"google.golang.org/grpc"
)

const (
TestNet = "testnet"
MainNet = "mainnet"
)

// Config uses envconfig to load the required settings from the environment, parse and
// validate them in preparation for running the GDS BFF API service.
type Config struct {
Expand Down
2 changes: 1 addition & 1 deletion pkg/bff/db/models/v1/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var (
AllowPartial: true,
UseProtoNames: true,
UseEnumNumbers: false,
EmitUnpopulated: false,
EmitUnpopulated: true,
}
pbdecoder = protojson.UnmarshalOptions{
AllowPartial: true,
Expand Down
35 changes: 35 additions & 0 deletions pkg/bff/db/models/v1/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package models_test

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
"github.com/trisacrypto/directory/pkg/bff/db/models/v1"
"google.golang.org/protobuf/proto"
)

// Test that the registration form marshals and unmarshals correctly to and from JSON
func TestMarshalRegistrationForm(t *testing.T) {
// Empty form should be marshaled correctly and contain default values
form := &models.RegistrationForm{}
data, err := json.Marshal(form)
require.NoError(t, err, "error marshaling empty registration form to JSON")
require.Greater(t, len(string(data)), 2, "missing fields should be populated in marshaled JSON")

// Empty form should be unmarshaled correctly
require.NoError(t, json.Unmarshal(data, form), "error unmarshaling empty registration form from JSON")
require.True(t, proto.Equal(&models.RegistrationForm{}, form), "empty registration form should be unmarshaled correctly")

// Form with data should be marshaled correctly
form = &models.RegistrationForm{
Website: "https://alice.example.com",
}
data, err = json.Marshal(form)
require.NoError(t, err, "error marshaling registration form to JSON")

// Form with data should be unmarshaled correctly
result := &models.RegistrationForm{}
require.NoError(t, json.Unmarshal(data, result), "error unmarshaling registration form from JSON")
require.True(t, proto.Equal(form, result), "registration form should be unmarshaled correctly")
}
5 changes: 3 additions & 2 deletions pkg/bff/db/models/v1/organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"

"github.com/google/uuid"
"github.com/trisacrypto/directory/pkg/bff/config"
)

var (
Expand Down Expand Up @@ -64,11 +65,11 @@ func (r *RegistrationForm) ReadyToSubmit(network string) bool {
}

switch network {
case "testnet":
case config.TestNet:
if r.Testnet == nil {
return false
}
case "mainnet":
case config.MainNet:
if r.Mainnet == nil {
return false
}
Expand Down
Loading

0 comments on commit 271d164

Please sign in to comment.