// RotateKey supports only timestamp and snapshot key rotation func TestRotateKeyEndpoint(t *testing.T) { ctx := context.WithValue( context.Background(), notary.CtxKeyMetaStore, storage.NewMemStorage()) ctx = context.WithValue(ctx, notary.CtxKeyKeyAlgo, data.ED25519Key) ccc := utils.NewCacheControlConfig(10, false) handler := RootHandler(ctx, nil, signed.NewEd25519(), ccc, ccc, nil) ts := httptest.NewServer(handler) defer ts.Close() rolesToStatus := map[string]int{ data.CanonicalTimestampRole: http.StatusOK, data.CanonicalSnapshotRole: http.StatusOK, data.CanonicalTargetsRole: http.StatusNotFound, data.CanonicalRootRole: http.StatusNotFound, "targets/delegation": http.StatusNotFound, "somerandomrole": http.StatusNotFound, } var buf bytes.Buffer for role, expectedStatus := range rolesToStatus { res, err := http.Post( fmt.Sprintf("%s/v2/gun/_trust/tuf/%s.key", ts.URL, role), "text/plain", &buf) require.NoError(t, err) require.Equal(t, expectedStatus, res.StatusCode) } }
// Parse the cache configurations for GET-ting current and checksummed metadata, // returning the configuration for current (non-content-addressed) metadata // first, then the configuration for consistent (content-addressed) metadata // second. The configuration consists mainly of the max-age (an integer in seconds, // just like in the Cache-Control header) for each type of metadata. // The max-age must be between 0 and 31536000 (one year in seconds, which is // the recommended maximum time data is cached), else parsing will return an error. // A max-age of 0 will disable caching for that type of download (consistent or current). func getCacheConfig(configuration *viper.Viper) (current, consistent utils.CacheControlConfig, err error) { cccs := make(map[string]utils.CacheControlConfig) currentOpt, consistentOpt := "current_metadata", "consistent_metadata" defaults := map[string]int{ currentOpt: int(notary.CurrentMetadataCacheMaxAge.Seconds()), consistentOpt: int(notary.ConsistentMetadataCacheMaxAge.Seconds()), } maxMaxAge := int(notary.CacheMaxAgeLimit.Seconds()) for optionName, seconds := range defaults { m := configuration.GetString(fmt.Sprintf("caching.max_age.%s", optionName)) if m != "" { seconds, err = strconv.Atoi(m) if err != nil || seconds < 0 || seconds > maxMaxAge { return nil, nil, fmt.Errorf( "must specify a cache-control max-age between 0 and %v", maxMaxAge) } } cccs[optionName] = utils.NewCacheControlConfig(seconds, optionName == currentOpt) } current = cccs[currentOpt] consistent = cccs[consistentOpt] return }
// This just checks the URL routing is working correctly and cache headers are set correctly. // More detailed tests for this path including negative // tests are located in /server/handlers/ func TestGetCurrentRole(t *testing.T) { store := storage.NewMemStorage() metadata, _, err := testutils.NewRepoMetadata("gun") require.NoError(t, err) // need both the snapshot and the timestamp, because when getting the current // timestamp the server checks to see if it's out of date (there's a new snapshot) // and if so, generates a new one store.UpdateCurrent("gun", storage.MetaUpdate{ Role: data.CanonicalSnapshotRole, Version: 1, Data: metadata[data.CanonicalSnapshotRole], }) store.UpdateCurrent("gun", storage.MetaUpdate{ Role: data.CanonicalTimestampRole, Version: 1, Data: metadata[data.CanonicalTimestampRole], }) ctx := context.WithValue( context.Background(), notary.CtxKeyMetaStore, store) ctx = context.WithValue(ctx, notary.CtxKeyKeyAlgo, data.ED25519Key) ccc := utils.NewCacheControlConfig(10, false) handler := RootHandler(ctx, nil, signed.NewEd25519(), ccc, ccc, nil) serv := httptest.NewServer(handler) defer serv.Close() res, err := http.Get(fmt.Sprintf( "%s/v2/gun/_trust/tuf/%s.json", serv.URL, data.CanonicalTimestampRole, )) require.NoError(t, err) require.Equal(t, http.StatusOK, res.StatusCode) verifyGetResponse(t, res, metadata[data.CanonicalTimestampRole]) }
// This just checks the URL routing is working correctly and cache headers are set correctly. // More detailed tests for this path including negative // tests are located in /server/handlers/ func TestGetRoleByHash(t *testing.T) { store := storage.NewMemStorage() ts := data.SignedTimestamp{ Signatures: make([]data.Signature, 0), Signed: data.Timestamp{ SignedCommon: data.SignedCommon{ Type: data.TUFTypes[data.CanonicalTimestampRole], Version: 1, Expires: data.DefaultExpires(data.CanonicalTimestampRole), }, }, } j, err := json.Marshal(&ts) require.NoError(t, err) store.UpdateCurrent("gun", storage.MetaUpdate{ Role: data.CanonicalTimestampRole, Version: 1, Data: j, }) checksumBytes := sha256.Sum256(j) checksum := hex.EncodeToString(checksumBytes[:]) // create and add a newer timestamp. We're going to try and request // the older version we created above. ts = data.SignedTimestamp{ Signatures: make([]data.Signature, 0), Signed: data.Timestamp{ SignedCommon: data.SignedCommon{ Type: data.TUFTypes[data.CanonicalTimestampRole], Version: 2, Expires: data.DefaultExpires(data.CanonicalTimestampRole), }, }, } newTS, err := json.Marshal(&ts) require.NoError(t, err) store.UpdateCurrent("gun", storage.MetaUpdate{ Role: data.CanonicalTimestampRole, Version: 1, Data: newTS, }) ctx := context.WithValue( context.Background(), notary.CtxKeyMetaStore, store) ctx = context.WithValue(ctx, notary.CtxKeyKeyAlgo, data.ED25519Key) ccc := utils.NewCacheControlConfig(10, false) handler := RootHandler(ctx, nil, signed.NewEd25519(), ccc, ccc, nil) serv := httptest.NewServer(handler) defer serv.Close() res, err := http.Get(fmt.Sprintf( "%s/v2/gun/_trust/tuf/%s.%s.json", serv.URL, data.CanonicalTimestampRole, checksum, )) require.NoError(t, err) require.Equal(t, http.StatusOK, res.StatusCode) // if content is equal, checksums are guaranteed to be equal verifyGetResponse(t, res, j) }