diff options
| author | simponic <simponic@hatecomputers.club> | 2024-03-28 16:58:07 -0400 |
|---|---|---|
| committer | simponic <simponic@hatecomputers.club> | 2024-03-28 16:58:07 -0400 |
| commit | 60fc4ebb599d82f5c7ddaca52f8aba74f0876381 (patch) | |
| tree | abe1eebb6154453cfa67812d7dfc982d758931a0 /api | |
| parent | dee173cc63d3b51d47c1a321096a4963fe458075 (diff) | |
| download | hatecomputers.club-60fc4ebb599d82f5c7ddaca52f8aba74f0876381.tar.gz hatecomputers.club-60fc4ebb599d82f5c7ddaca52f8aba74f0876381.zip | |
internal recursive dns server (#2)
Co-authored-by: Lizzy Hunt <lizzy.hunt@usu.edu>
Reviewed-on: https://git.hatecomputers.club/hatecomputers/hatecomputers.club/pulls/2
Diffstat (limited to 'api')
| -rw-r--r-- | api/dns.go | 74 |
1 files changed, 52 insertions, 22 deletions
@@ -1,6 +1,7 @@ package api import ( + "database/sql" "log" "net/http" "strconv" @@ -8,16 +9,31 @@ import ( "git.hatecomputers.club/hatecomputers/hatecomputers.club/adapters/cloudflare" "git.hatecomputers.club/hatecomputers/hatecomputers.club/database" + "git.hatecomputers.club/hatecomputers/hatecomputers.club/utils" ) -const MAX_USER_RECORDS = 20 +const MAX_USER_RECORDS = 65 type FormError struct { Errors []string } -func userCanFuckWithDNSRecord(user *database.User, record *database.DNSRecord) bool { - return user.ID == record.UserID && (record.Name == user.Username || strings.HasSuffix(record.Name, "."+user.Username)) +func userCanFuckWithDNSRecord(dbConn *sql.DB, user *database.User, record *database.DNSRecord) bool { + ownedByUser := (user.ID == record.UserID) + + if !record.Internal { + publicallyOwnedByUser := (record.Name == user.Username || strings.HasSuffix(record.Name, "."+user.Username)) + return ownedByUser && publicallyOwnedByUser + } + + owner, err := database.FindFirstDomainOwnerId(dbConn, record.Name) + if err != nil { + log.Println(err) + return false + } + + userIsOwnerOfDomain := owner == user.ID + return ownedByUser && userIsOwnerOfDomain } func ListDNSRecordsContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { @@ -40,8 +56,15 @@ func CreateDNSRecordContinuation(context *RequestContext, req *http.Request, res Errors: []string{}, } + internal := req.FormValue("internal") == "on" name := req.FormValue("name") + if internal && !strings.HasSuffix(name, ".") { + name += "." + } + recordType := req.FormValue("type") + recordType = strings.ToUpper(recordType) + recordContent := req.FormValue("content") ttl := req.FormValue("ttl") ttlNum, err := strconv.Atoi(ttl) @@ -50,11 +73,12 @@ func CreateDNSRecordContinuation(context *RequestContext, req *http.Request, res } dnsRecord := &database.DNSRecord{ - UserID: context.User.ID, - Name: name, - Type: recordType, - Content: recordContent, - TTL: ttlNum, + UserID: context.User.ID, + Name: name, + Type: recordType, + Content: recordContent, + TTL: ttlNum, + Internal: internal, } dnsRecords, err := database.GetUserDNSRecords(context.DBConn, context.User.ID) @@ -67,18 +91,22 @@ func CreateDNSRecordContinuation(context *RequestContext, req *http.Request, res formErrors.Errors = append(formErrors.Errors, "max records reached") } - if !userCanFuckWithDNSRecord(context.User, dnsRecord) { - formErrors.Errors = append(formErrors.Errors, "'name' must end with "+context.User.Username) + if !userCanFuckWithDNSRecord(context.DBConn, context.User, dnsRecord) { + formErrors.Errors = append(formErrors.Errors, "'name' must end with "+context.User.Username+" or you must be a domain owner for internal domains") } if len(formErrors.Errors) == 0 { - cloudflareRecordId, err := cloudflare.CreateDNSRecord(context.Args.CloudflareZone, context.Args.CloudflareToken, dnsRecord) - if err != nil { - log.Println(err) - formErrors.Errors = append(formErrors.Errors, err.Error()) + if dnsRecord.Internal { + dnsRecord.ID = utils.RandomId() + } else { + cloudflareRecordId, err := cloudflare.CreateDNSRecord(context.Args.CloudflareZone, context.Args.CloudflareToken, dnsRecord) + if err != nil { + log.Println(err) + formErrors.Errors = append(formErrors.Errors, err.Error()) + } + + dnsRecord.ID = cloudflareRecordId } - - dnsRecord.ID = cloudflareRecordId } if len(formErrors.Errors) == 0 { @@ -113,16 +141,18 @@ func DeleteDNSRecordContinuation(context *RequestContext, req *http.Request, res return failure(context, req, resp) } - if !userCanFuckWithDNSRecord(context.User, record) { + if !userCanFuckWithDNSRecord(context.DBConn, context.User, record) { resp.WriteHeader(http.StatusUnauthorized) return failure(context, req, resp) } - err = cloudflare.DeleteDNSRecord(context.Args.CloudflareZone, context.Args.CloudflareToken, recordId) - if err != nil { - log.Println(err) - resp.WriteHeader(http.StatusInternalServerError) - return failure(context, req, resp) + if !record.Internal { + err = cloudflare.DeleteDNSRecord(context.Args.CloudflareZone, context.Args.CloudflareToken, recordId) + if err != nil { + log.Println(err) + resp.WriteHeader(http.StatusInternalServerError) + return failure(context, req, resp) + } } err = database.DeleteDNSRecord(context.DBConn, recordId) |
