Example #1
0
func (h *DomainHandler) Put(w http.ResponseWriter, r *http.Request) {
	// We need to set the FQDN in the domain request object because it is sent only in the
	// URI and not in the domain request body to avoid information redudancy
	h.Request.FQDN = h.GetFQDN()

	var err error
	if h.domain, err = protocol.Merge(h.domain, h.Request); err != nil {
		messageId := ""

		switch err {
		case model.ErrInvalidFQDN:
			messageId = "invalid-fqdn"
		case protocol.ErrInvalidDNSKEY:
			messageId = "invalid-dnskey"
		case protocol.ErrInvalidDSAlgorithm:
			messageId = "invalid-ds-algorithm"
		case protocol.ErrInvalidDSDigestType:
			messageId = "invalid-ds-digest-type"
		case protocol.ErrInvalidIP:
			messageId = "invalid-ip"
		case protocol.ErrInvalidLanguage:
			messageId = "invalid-language"
		}

		if len(messageId) == 0 {
			log.Println("Error while merging domain objects for create or "+
				"update operation. Details:", err)
			w.WriteHeader(http.StatusInternalServerError)

		} else {
			if err := h.MessageResponse(messageId, r.URL.RequestURI()); err == nil {
				w.WriteHeader(http.StatusBadRequest)

			} else {
				log.Println("Error while writing response. Details:", err)
				w.WriteHeader(http.StatusInternalServerError)
			}
		}
		return
	}

	domainDAO := dao.DomainDAO{
		Database: h.GetDatabase(),
	}

	if err := domainDAO.Save(&h.domain); err != nil {
		if strings.Index(err.Error(), "duplicate key error index") != -1 {
			if err := h.MessageResponse("conflict", r.URL.RequestURI()); err == nil {
				w.WriteHeader(http.StatusConflict)

			} else {
				log.Println("Error while writing response. Details:", err)
				w.WriteHeader(http.StatusInternalServerError)
			}

		} else {
			log.Println("Error while saving domain object for create or "+
				"update operation. Details:", err)
			w.WriteHeader(http.StatusInternalServerError)
		}

		return
	}

	w.Header().Add("ETag", h.GetETag())
	w.Header().Add("Last-Modified", h.GetLastModifiedAt().Format(time.RFC1123))

	if h.domain.Revision == 1 {
		w.Header().Add("Location", "/domain/"+h.domain.FQDN)
		w.WriteHeader(http.StatusCreated)

	} else {
		w.WriteHeader(http.StatusNoContent)
	}
}
// Put is responsable for checking a domain object on-the-fly without persisting in
// database, useful for pre-registration validations in the registry
func (h *DomainVerificationHandler) Put(w http.ResponseWriter, r *http.Request) {
	// We need to set the FQDN in the domain request object because it is sent only in the
	// URI and not in the domain request body to avoid information redudancy
	h.Request.FQDN = h.GetFQDN()

	var domain model.Domain
	var err error

	if domain, err = protocol.Merge(domain, h.Request); err != nil {
		messageId := ""

		switch err {
		case protocol.ErrInvalidDNSKEY:
			messageId = "invalid-dnskey"
		case protocol.ErrInvalidDSAlgorithm:
			messageId = "invalid-ds-algorithm"
		case protocol.ErrInvalidDSDigestType:
			messageId = "invalid-ds-digest-type"
		case protocol.ErrInvalidIP:
			messageId = "invalid-ip"
		case protocol.ErrInvalidLanguage:
			messageId = "invalid-language"
		}

		if len(messageId) == 0 {
			log.Println("Error while merging domain objects for domain verification "+
				"operation. Details:", err)
			w.WriteHeader(http.StatusInternalServerError)

		} else {
			if err := h.MessageResponse(messageId, r.URL.RequestURI()); err == nil {
				w.WriteHeader(http.StatusBadRequest)

			} else {
				log.Println("Error while writing response. Details:", err)
				w.WriteHeader(http.StatusInternalServerError)
			}
		}
		return
	}

	scan.ScanDomain(&domain)

	// As we alredy did the scan, if the domain is registered in the system, we update it for this
	// results. This also gives a more intuitive design for when the user wants to force a check a
	// specific domain in the Shelter system
	domainDAO := dao.DomainDAO{
		Database: h.GetDatabase(),
	}

	if dbDomain, err := domainDAO.FindByFQDN(domain.FQDN); err == nil {
		update := true

		// Check if we have the same nameservers, and if so update the last status
		if len(dbDomain.Nameservers) == len(domain.Nameservers) {
			for i := range dbDomain.Nameservers {
				dbNameserver := dbDomain.Nameservers[i]
				nameserver := domain.Nameservers[i]

				if dbNameserver.Host == nameserver.Host &&
					dbNameserver.IPv4.Equal(nameserver.IPv4) &&
					dbNameserver.IPv6.Equal(nameserver.IPv6) {

					dbDomain.Nameservers[i].ChangeStatus(nameserver.LastStatus)

				} else {
					update = false
					break
				}
			}

		} else {
			update = false
		}

		// Check if we have the same DS set, and if so update the last status
		if len(dbDomain.DSSet) == len(domain.DSSet) {
			for i := range dbDomain.DSSet {
				dbDS := dbDomain.DSSet[i]
				ds := domain.DSSet[i]

				if dbDS.Keytag == ds.Keytag &&
					dbDS.Algorithm == ds.Algorithm &&
					dbDS.DigestType == ds.DigestType &&
					dbDS.Digest == ds.Digest {

					dbDomain.DSSet[i].ChangeStatus(ds.LastStatus)

				} else {
					update = false
					break
				}
			}

		} else {
			update = false
		}

		if update {
			// We don't care about errors resulted here, because the main idea of this service is to scan
			// a domaion, not persist the results
			domainDAO.Save(&dbDomain)
		}
	}

	w.WriteHeader(http.StatusOK)
	domainResponse := protocol.ToDomainResponse(domain, false)
	h.Response = &domainResponse
}