checkpoint to save work; had to get on the bus
	
		
			
	
		
	
	
		
			
				
	
				continuous-integration/drone/pr Build is failing
				
					Details
				
			
		
	
				
					
				
			
				
	
				continuous-integration/drone/pr Build is failing
				
					Details
				
			
		
	This commit is contained in:
		
							parent
							
								
									b74a955dcb
								
							
						
					
					
						commit
						e398cf0540
					
				|  | @ -0,0 +1,37 @@ | ||||||
|  | package api_test | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"database/sql" | ||||||
|  | 	"os" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/api" | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/args" | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/database" | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/utils" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func setup() (*sql.DB, *api.RequestContext, func()) { | ||||||
|  | 	randomDb := utils.RandomId() | ||||||
|  | 
 | ||||||
|  | 	testDb := database.MakeConn(&randomDb) | ||||||
|  | 	database.Migrate(testDb) | ||||||
|  | 
 | ||||||
|  | 	context := &api.RequestContext{ | ||||||
|  | 		DBConn:       testDb, | ||||||
|  | 		Args:         &args.Arguments{}, | ||||||
|  | 		TemplateData: &(map[string]interface{}{}), | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return testDb, context, func() { | ||||||
|  | 		testDb.Close() | ||||||
|  | 		os.Remove(randomDb) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | todo: test api key creation | ||||||
|  | + api key attached to user | ||||||
|  | + user session is unique | ||||||
|  | + goLogin goes to page in cookie | ||||||
|  | */ | ||||||
							
								
								
									
										17
									
								
								api/dns.go
								
								
								
								
							
							
						
						
									
										17
									
								
								api/dns.go
								
								
								
								
							|  | @ -15,23 +15,18 @@ import ( | ||||||
| 
 | 
 | ||||||
| const MAX_USER_RECORDS = 65 | const MAX_USER_RECORDS = 65 | ||||||
| 
 | 
 | ||||||
| type FormError struct { | var USER_OWNED_INTERNAL_FMT_DOMAINS = []string{"%s", "%s.endpoints"} | ||||||
| 	Errors []string |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| func userCanFuckWithDNSRecord(dbConn *sql.DB, user *database.User, record *database.DNSRecord) bool { | func userCanFuckWithDNSRecord(dbConn *sql.DB, user *database.User, record *database.DNSRecord, ownedInternalDomainFormats []string) bool { | ||||||
| 	ownedByUser := (user.ID == record.UserID) | 	ownedByUser := (user.ID == record.UserID) | ||||||
| 	if !ownedByUser { | 	if !ownedByUser { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !record.Internal { | 	if !record.Internal { | ||||||
| 		userOwnedDomains := []string{ | 		for _, format := range ownedInternalDomainFormats { | ||||||
| 			fmt.Sprintf("%s", user.Username), | 			domain := fmt.Sprintf(format, user.Username) | ||||||
| 			fmt.Sprintf("%s.endpoints", user.Username), |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		for _, domain := range userOwnedDomains { |  | ||||||
| 			isInSubDomain := strings.HasSuffix(record.Name, "."+domain) | 			isInSubDomain := strings.HasSuffix(record.Name, "."+domain) | ||||||
| 			if domain == record.Name || isInSubDomain { | 			if domain == record.Name || isInSubDomain { | ||||||
| 				return true | 				return true | ||||||
|  | @ -106,7 +101,7 @@ func CreateDNSRecordContinuation(dnsAdapter external_dns.ExternalDNSAdapter) fun | ||||||
| 				Internal: internal, | 				Internal: internal, | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if !userCanFuckWithDNSRecord(context.DBConn, context.User, dnsRecord) { | 			if !userCanFuckWithDNSRecord(context.DBConn, context.User, dnsRecord, USER_OWNED_INTERNAL_FMT_DOMAINS) { | ||||||
| 				formErrors.Errors = append(formErrors.Errors, "'name' must end with "+context.User.Username+" or you must be a domain owner for internal domains") | 				formErrors.Errors = append(formErrors.Errors, "'name' must end with "+context.User.Username+" or you must be a domain owner for internal domains") | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -155,7 +150,7 @@ func DeleteDNSRecordContinuation(dnsAdapter external_dns.ExternalDNSAdapter) fun | ||||||
| 				return failure(context, req, resp) | 				return failure(context, req, resp) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if !userCanFuckWithDNSRecord(context.DBConn, context.User, record) { | 			if !userCanFuckWithDNSRecord(context.DBConn, context.User, record, USER_OWNED_INTERNAL_FMT_DOMAINS) { | ||||||
| 				resp.WriteHeader(http.StatusUnauthorized) | 				resp.WriteHeader(http.StatusUnauthorized) | ||||||
| 				return failure(context, req, resp) | 				return failure(context, req, resp) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,56 @@ | ||||||
|  | package api_test | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"database/sql" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/http/httptest" | ||||||
|  | 	"os" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/api" | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/args" | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/database" | ||||||
|  | 	"git.hatecomputers.club/hatecomputers/hatecomputers.club/utils" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func setup() (*sql.DB, *api.RequestContext, func()) { | ||||||
|  | 	randomDb := utils.RandomId() | ||||||
|  | 
 | ||||||
|  | 	testDb := database.MakeConn(&randomDb) | ||||||
|  | 	database.Migrate(testDb) | ||||||
|  | 
 | ||||||
|  | 	context := &api.RequestContext{ | ||||||
|  | 		DBConn:       testDb, | ||||||
|  | 		Args:         &args.Arguments{}, | ||||||
|  | 		TemplateData: &(map[string]interface{}{}), | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return testDb, context, func() { | ||||||
|  | 		testDb.Close() | ||||||
|  | 		os.Remove(randomDb) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestThatOwnerCanPutRecordInDomain(t *testing.T) { | ||||||
|  | 	db, context, cleanup := setup() | ||||||
|  | 	defer cleanup() | ||||||
|  | 
 | ||||||
|  | 	testUser := &database.User{ | ||||||
|  | 		ID:       "test", | ||||||
|  | 		Username: "test", | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	records, err := database.GetUserDNSRecords(db, context.User.ID) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 	if len(records) > 0 { | ||||||
|  | 		t.Errorf("expected no records, got records") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		api.PutDNSRecordContinuation(context, r, w)(api.IdContinuation, api.IdContinuation) | ||||||
|  | 	})) | ||||||
|  | 	defer ts.Close() | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -24,6 +24,10 @@ type RequestContext struct { | ||||||
| 	User         *database.User | 	User         *database.User | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type FormError struct { | ||||||
|  | 	Errors []string | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type Continuation func(*RequestContext, *http.Request, http.ResponseWriter) ContinuationChain | type Continuation func(*RequestContext, *http.Request, http.ResponseWriter) ContinuationChain | ||||||
| type ContinuationChain func(Continuation, Continuation) ContinuationChain | type ContinuationChain func(Continuation, Continuation) ContinuationChain | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue