Use identifiers globally
This commit is contained in:
parent
5e65e727ad
commit
c29a8fa57f
|
@ -35,7 +35,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
@ -96,7 +95,7 @@ func newDomain(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ud.Id = 0
|
ud.Id = nil
|
||||||
ud.IdUser = user.Id
|
ud.IdUser = user.Id
|
||||||
|
|
||||||
ApiResponse(c, ud, storage.MainStore.CreateDomain(user, ud))
|
ApiResponse(c, ud, storage.MainStore.CreateDomain(user, ud))
|
||||||
|
@ -126,7 +125,7 @@ func updateUserDomain(c *gin.Context) {
|
||||||
func deleteUserDomain(c *gin.Context) {
|
func deleteUserDomain(c *gin.Context) {
|
||||||
user := c.MustGet("user").(*happydns.User)
|
user := c.MustGet("user").(*happydns.User)
|
||||||
|
|
||||||
domainid, err := strconv.ParseInt(c.Param("domain"), 10, 64)
|
domainid, err := happydns.NewIdentifierFromString(c.Param("domain"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
domain, err := storage.MainStore.GetDomainByDN(user, c.Param("domain"))
|
domain, err := storage.MainStore.GetDomainByDN(user, c.Param("domain"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -136,7 +136,7 @@ func newUserProvider(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
us.Id = 0
|
us.Id = nil
|
||||||
|
|
||||||
src, err := storage.MainStore.CreateProvider(user.(*happydns.User), us, "")
|
src, err := storage.MainStore.CreateProvider(user.(*happydns.User), us, "")
|
||||||
ApiResponse(c, src, err)
|
ApiResponse(c, src, err)
|
||||||
|
|
|
@ -35,7 +35,6 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ func newUserDomainZone(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uz.Id = 0
|
uz.Id = nil
|
||||||
|
|
||||||
ApiResponse(c, uz, storage.MainStore.CreateZone(uz))
|
ApiResponse(c, uz, storage.MainStore.CreateZone(uz))
|
||||||
}
|
}
|
||||||
|
@ -167,7 +166,7 @@ func patchZoneService(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteZone(c *gin.Context) {
|
func deleteZone(c *gin.Context) {
|
||||||
zoneid, err := strconv.ParseInt(c.Param("zoneid"), 10, 64)
|
zoneid, err := happydns.NewIdentifierFromString(c.Param("zoneid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": err.Error()})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": err.Error()})
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -128,7 +128,13 @@ func DomainHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
domain, err := storage.MainStore.GetDomainByDN(user, c.Param("domain"))
|
dnid, err := happydns.NewIdentifierFromString(c.Param("domain"))
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Invalid domain identifier: %s", err.Error())})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
domain, err := storage.MainStore.GetDomain(user, dnid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Domain not found"})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Domain not found"})
|
||||||
return
|
return
|
||||||
|
@ -141,7 +147,7 @@ func DomainHandler(c *gin.Context) {
|
||||||
} else if src, exists := c.Get("sourcemeta"); exists {
|
} else if src, exists := c.Get("sourcemeta"); exists {
|
||||||
source = src.(*happydns.SourceMeta)
|
source = src.(*happydns.SourceMeta)
|
||||||
}
|
}
|
||||||
if source != nil && source.Id != domain.IdProvider {
|
if source != nil && !source.Id.Equals(domain.IdProvider) {
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Domain not found (not child of source)"})
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Domain not found (not child of source)"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -152,9 +158,9 @@ func DomainHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiDomain struct {
|
type apiDomain struct {
|
||||||
Id int64 `json:"id"`
|
Id happydns.Identifier `json:"id"`
|
||||||
IdUser []byte `json:"id_owner"`
|
IdUser happydns.Identifier `json:"id_owner"`
|
||||||
IdProvider int64 `json:"id_provider"`
|
IdProvider happydns.Identifier `json:"id_provider"`
|
||||||
DomainName string `json:"domain"`
|
DomainName string `json:"domain"`
|
||||||
ZoneHistory []happydns.ZoneMeta `json:"zone_history"`
|
ZoneHistory []happydns.ZoneMeta `json:"zone_history"`
|
||||||
Group string `json:"group,omitempty"`
|
Group string `json:"group,omitempty"`
|
||||||
|
@ -194,7 +200,7 @@ func UpdateDomain(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if old.Id != domain.Id {
|
if !old.Id.Equals(domain.Id) {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "You cannot change the domain reserved ID"})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "You cannot change the domain reserved ID"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ func getProviderSettingsState(cfg *config.Options, c *gin.Context) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// Update an existing Provider
|
// Update an existing Provider
|
||||||
s, err := storage.MainStore.GetProvider(user, int64(uss.Id.(float64)))
|
s, err := storage.MainStore.GetProvider(user, uss.Id.(happydns.Identifier))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||||
return
|
return
|
||||||
|
|
|
@ -35,7 +35,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
dnscontrol "github.com/StackExchange/dnscontrol/v3/providers"
|
dnscontrol "github.com/StackExchange/dnscontrol/v3/providers"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -110,7 +109,7 @@ func DecodeProvider(c *gin.Context) (*happydns.ProviderCombined, int, error) {
|
||||||
|
|
||||||
func ProviderMetaHandler(c *gin.Context) {
|
func ProviderMetaHandler(c *gin.Context) {
|
||||||
// Extract provider ID
|
// Extract provider ID
|
||||||
pid, err := strconv.ParseInt(string(c.Param("pid")), 10, 64)
|
pid, err := happydns.NewIdentifierFromString(string(c.Param("pid")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Invalid provider id: %s", err.Error())})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Invalid provider id: %s", err.Error())})
|
||||||
return
|
return
|
||||||
|
@ -138,7 +137,7 @@ func ProviderMetaHandler(c *gin.Context) {
|
||||||
|
|
||||||
func ProviderHandler(c *gin.Context) {
|
func ProviderHandler(c *gin.Context) {
|
||||||
// Extract provider ID
|
// Extract provider ID
|
||||||
pid, err := strconv.ParseInt(string(c.Param("pid")), 10, 64)
|
pid, err := happydns.NewIdentifierFromString(string(c.Param("pid")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Invalid provider id: %s", err.Error())})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Invalid provider id: %s", err.Error())})
|
||||||
return
|
return
|
||||||
|
@ -224,7 +223,7 @@ func deleteProvider(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
if domain.IdProvider == providermeta.Id {
|
if domain.IdProvider.Equals(providermeta.Id) {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "You cannot delete this provider because there is still some domains associated with it."})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "You cannot delete this provider because there is still some domains associated with it."})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ func declareAuthenticationRoutes(opts *config.Options, router *gin.RouterGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DisplayUser struct {
|
type DisplayUser struct {
|
||||||
Id happydns.HexaString `json:"id"`
|
Id happydns.Identifier `json:"id"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
Settings happydns.UserSettings `json:"settings,omitempty"`
|
Settings happydns.UserSettings `json:"settings,omitempty"`
|
||||||
|
|
|
@ -33,7 +33,7 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -356,7 +356,7 @@ func deleteUser(opts *config.Options, c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserHandlerBase(c *gin.Context) (*happydns.User, error) {
|
func UserHandlerBase(c *gin.Context) (*happydns.User, error) {
|
||||||
uid, err := hex.DecodeString(c.Param("uid"))
|
uid, err := base64.RawURLEncoding.DecodeString(c.Param("uid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Invalid user identifier given: %w", err)
|
return nil, fmt.Errorf("Invalid user identifier given: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -382,7 +382,7 @@ func userHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserAuthHandlerBase(c *gin.Context) (*happydns.UserAuth, error) {
|
func UserAuthHandlerBase(c *gin.Context) (*happydns.UserAuth, error) {
|
||||||
uid, err := hex.DecodeString(c.Param("uid"))
|
uid, err := base64.RawURLEncoding.DecodeString(c.Param("uid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Invalid user identifier given: %w", err)
|
return nil, fmt.Errorf("Invalid user identifier given: %w", err)
|
||||||
}
|
}
|
||||||
|
|
16
api/zones.go
16
api/zones.go
|
@ -32,11 +32,9 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -78,7 +76,7 @@ func declareZonesRoutes(cfg *config.Options, router *gin.RouterGroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadZoneFromId(domain *happydns.Domain, id string) (*happydns.Zone, int, error) {
|
func loadZoneFromId(domain *happydns.Domain, id string) (*happydns.Zone, int, error) {
|
||||||
zoneid, err := strconv.ParseInt(id, 10, 64)
|
zoneid, err := happydns.NewIdentifierFromString(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, http.StatusBadRequest, fmt.Errorf("Invalid zoneid: %q", id)
|
return nil, http.StatusBadRequest, fmt.Errorf("Invalid zoneid: %q", id)
|
||||||
}
|
}
|
||||||
|
@ -168,7 +166,7 @@ func addZoneService(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceIdHandler(c *gin.Context) {
|
func serviceIdHandler(c *gin.Context) {
|
||||||
serviceid, err := hex.DecodeString(c.Param("serviceid"))
|
serviceid, err := happydns.NewIdentifierFromString(c.Param("serviceid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Bad service identifier: %s", err.Error())})
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Bad service identifier: %s", err.Error())})
|
||||||
return
|
return
|
||||||
|
@ -226,7 +224,7 @@ func importZone(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
domain.ZoneHistory = append(
|
domain.ZoneHistory = append(
|
||||||
[]int64{myZone.Id}, domain.ZoneHistory...)
|
[]happydns.Identifier{myZone.Id}, domain.ZoneHistory...)
|
||||||
|
|
||||||
// Create wip zone
|
// Create wip zone
|
||||||
err = storage.MainStore.CreateZone(myZone)
|
err = storage.MainStore.CreateZone(myZone)
|
||||||
|
@ -236,7 +234,7 @@ func importZone(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
domain.ZoneHistory = append(
|
domain.ZoneHistory = append(
|
||||||
[]int64{myZone.Id}, domain.ZoneHistory...)
|
[]happydns.Identifier{myZone.Id}, domain.ZoneHistory...)
|
||||||
|
|
||||||
err = storage.MainStore.UpdateDomain(domain)
|
err = storage.MainStore.UpdateDomain(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -359,7 +357,7 @@ func applyZone(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
domain.ZoneHistory = append(
|
domain.ZoneHistory = append(
|
||||||
[]int64{newZone.Id}, domain.ZoneHistory...)
|
[]happydns.Identifier{newZone.Id}, domain.ZoneHistory...)
|
||||||
|
|
||||||
err = storage.MainStore.UpdateDomain(domain)
|
err = storage.MainStore.UpdateDomain(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -431,7 +429,7 @@ func UpdateZoneService(c *gin.Context) {
|
||||||
func deleteZoneService(c *gin.Context) {
|
func deleteZoneService(c *gin.Context) {
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
domain := c.MustGet("domain").(*happydns.Domain)
|
||||||
zone := c.MustGet("zone").(*happydns.Zone)
|
zone := c.MustGet("zone").(*happydns.Zone)
|
||||||
serviceid := c.MustGet("serviceid").([]byte)
|
serviceid := c.MustGet("serviceid").(happydns.Identifier)
|
||||||
subdomain := c.MustGet("subdomain").(string)
|
subdomain := c.MustGet("subdomain").(string)
|
||||||
|
|
||||||
err := zone.EraseService(subdomain, domain.DomainName, serviceid, nil)
|
err := zone.EraseService(subdomain, domain.DomainName, serviceid, nil)
|
||||||
|
@ -460,7 +458,7 @@ type serviceRecord struct {
|
||||||
func getServiceRecords(c *gin.Context) {
|
func getServiceRecords(c *gin.Context) {
|
||||||
domain := c.MustGet("domain").(*happydns.Domain)
|
domain := c.MustGet("domain").(*happydns.Domain)
|
||||||
zone := c.MustGet("zone").(*happydns.Zone)
|
zone := c.MustGet("zone").(*happydns.Zone)
|
||||||
serviceid := c.MustGet("serviceid").([]byte)
|
serviceid := c.MustGet("serviceid").(happydns.Identifier)
|
||||||
subdomain := c.MustGet("subdomain").(string)
|
subdomain := c.MustGet("subdomain").(string)
|
||||||
|
|
||||||
svc := zone.FindSubdomainService(subdomain, serviceid)
|
svc := zone.FindSubdomainService(subdomain, serviceid)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"git.happydns.org/happydomain/model"
|
"git.happydns.org/happydomain/model"
|
||||||
|
@ -40,11 +41,11 @@ import (
|
||||||
// GetAccountRecoveryURL returns the absolute URL corresponding to the recovery
|
// GetAccountRecoveryURL returns the absolute URL corresponding to the recovery
|
||||||
// URL of the given account.
|
// URL of the given account.
|
||||||
func (o *Options) GetAccountRecoveryURL(u *happydns.UserAuth) string {
|
func (o *Options) GetAccountRecoveryURL(u *happydns.UserAuth) string {
|
||||||
return o.BuildURL_noescape("/forgotten-password?u=%x&k=%s", u.Id, url.QueryEscape(u.GenAccountRecoveryHash(false)))
|
return o.BuildURL_noescape("/forgotten-password?u=%s&k=%s", base64.RawURLEncoding.EncodeToString(u.Id), url.QueryEscape(u.GenAccountRecoveryHash(false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRegistrationURL returns the absolute URL corresponding to the e-mail
|
// GetRegistrationURL returns the absolute URL corresponding to the e-mail
|
||||||
// validation page of the given account.
|
// validation page of the given account.
|
||||||
func (o *Options) GetRegistrationURL(u *happydns.UserAuth) string {
|
func (o *Options) GetRegistrationURL(u *happydns.UserAuth) string {
|
||||||
return o.BuildURL_noescape("/email-validation?u=%x&k=%s", u.Id, url.QueryEscape(u.GenRegistrationHash(false)))
|
return o.BuildURL_noescape("/email-validation?u=%s&k=%s", base64.RawURLEncoding.EncodeToString(u.Id), url.QueryEscape(u.GenRegistrationHash(false)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,14 @@ import (
|
||||||
// Domain holds information about a domain name own by a User.
|
// Domain holds information about a domain name own by a User.
|
||||||
type Domain struct {
|
type Domain struct {
|
||||||
// Id is the Domain's identifier in the database.
|
// Id is the Domain's identifier in the database.
|
||||||
Id int64 `json:"id"`
|
Id Identifier `json:"id"`
|
||||||
|
|
||||||
// IdUser is the identifier of the Domain's Owner.
|
// IdUser is the identifier of the Domain's Owner.
|
||||||
IdUser HexaString `json:"id_owner"`
|
IdUser Identifier `json:"id_owner"`
|
||||||
|
|
||||||
// IsProvider is the identifier of the Provider used to access and edit the
|
// IsProvider is the identifier of the Provider used to access and edit the
|
||||||
// Domain.
|
// Domain.
|
||||||
IdProvider int64 `json:"id_provider"`
|
IdProvider Identifier `json:"id_provider"`
|
||||||
|
|
||||||
// DomainName is the FQDN of the managed Domain.
|
// DomainName is the FQDN of the managed Domain.
|
||||||
DomainName string `json:"domain"`
|
DomainName string `json:"domain"`
|
||||||
|
@ -55,7 +55,7 @@ type Domain struct {
|
||||||
|
|
||||||
// ZoneHistory are the identifiers to the Zone attached to the current
|
// ZoneHistory are the identifiers to the Zone attached to the current
|
||||||
// Domain.
|
// Domain.
|
||||||
ZoneHistory []int64 `json:"zone_history"`
|
ZoneHistory []Identifier `json:"zone_history"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domains is an array of Domain.
|
// Domains is an array of Domain.
|
||||||
|
@ -63,9 +63,9 @@ type Domains []*Domain
|
||||||
|
|
||||||
// HasZone checks if the given Zone's identifier is part of this Domain
|
// HasZone checks if the given Zone's identifier is part of this Domain
|
||||||
// history.
|
// history.
|
||||||
func (d *Domain) HasZone(zoneId int64) (found bool) {
|
func (d *Domain) HasZone(zoneId Identifier) (found bool) {
|
||||||
for _, v := range d.ZoneHistory {
|
for _, v := range d.ZoneHistory {
|
||||||
if v == zoneId {
|
if v.Equals(zoneId) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright or © or Copr. happyDNS (2022)
|
||||||
|
//
|
||||||
|
// contact@happydomain.org
|
||||||
|
//
|
||||||
|
// This software is a computer program whose purpose is to provide a modern
|
||||||
|
// interface to interact with DNS systems.
|
||||||
|
//
|
||||||
|
// This software is governed by the CeCILL license under French law and abiding
|
||||||
|
// by the rules of distribution of free software. You can use, modify and/or
|
||||||
|
// redistribute the software under the terms of the CeCILL license as
|
||||||
|
// circulated by CEA, CNRS and INRIA at the following URL
|
||||||
|
// "http://www.cecill.info".
|
||||||
|
//
|
||||||
|
// As a counterpart to the access to the source code and rights to copy, modify
|
||||||
|
// and redistribute granted by the license, users are provided only with a
|
||||||
|
// limited warranty and the software's author, the holder of the economic
|
||||||
|
// rights, and the successive licensors have only limited liability.
|
||||||
|
//
|
||||||
|
// In this respect, the user's attention is drawn to the risks associated with
|
||||||
|
// loading, using, modifying and/or developing or reproducing the software by
|
||||||
|
// the user in light of its specific status of free software, that may mean
|
||||||
|
// that it is complicated to manipulate, and that also therefore means that it
|
||||||
|
// is reserved for developers and experienced professionals having in-depth
|
||||||
|
// computer knowledge. Users are therefore encouraged to load and test the
|
||||||
|
// software's suitability as regards their requirements in conditions enabling
|
||||||
|
// the security of their systems and/or data to be ensured and, more generally,
|
||||||
|
// to use and operate it in the same conditions as regards security.
|
||||||
|
//
|
||||||
|
// The fact that you are presently reading this means that you have had
|
||||||
|
// knowledge of the CeCILL license and that you accept its terms.
|
||||||
|
|
||||||
|
package happydns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const IDENTIFIER_LEN = 16
|
||||||
|
|
||||||
|
type Identifier []byte
|
||||||
|
|
||||||
|
func NewIdentifierFromString(src string) (id Identifier, err error) {
|
||||||
|
return base64.RawURLEncoding.DecodeString(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRandomIdentifier() (id Identifier, err error) {
|
||||||
|
id = make([]byte, IDENTIFIER_LEN)
|
||||||
|
|
||||||
|
if _, err = rand.Read(id); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Identifier) IsEmpty() bool {
|
||||||
|
return len(*i) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Identifier) Equals(other Identifier) bool {
|
||||||
|
return bytes.Equal(i, other)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Identifier) String() string {
|
||||||
|
return base64.RawURLEncoding.EncodeToString(*i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Identifier) MarshalJSON() (dst []byte, err error) {
|
||||||
|
dst = make([]byte, base64.RawURLEncoding.EncodedLen(len(i)))
|
||||||
|
base64.RawURLEncoding.Encode(dst, i)
|
||||||
|
dst = append([]byte{'"'}, dst...)
|
||||||
|
dst = append(dst, '"')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Identifier) UnmarshalJSON(src []byte) error {
|
||||||
|
if len(src) < 2 || src[0] != '"' || src[len(src)-1] != '"' {
|
||||||
|
return errors.New("Unvalid character found to encapsulate the JSON value")
|
||||||
|
}
|
||||||
|
|
||||||
|
*i = make([]byte, base64.RawURLEncoding.DecodedLen(len(src)-2))
|
||||||
|
_, err := base64.RawURLEncoding.Decode(*i, src[1:len(src)-1])
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
|
@ -52,10 +52,10 @@ type ProviderMeta struct {
|
||||||
Type string `json:"_srctype"`
|
Type string `json:"_srctype"`
|
||||||
|
|
||||||
// Id is the Provider's identifier.
|
// Id is the Provider's identifier.
|
||||||
Id int64 `json:"_id"`
|
Id Identifier `json:"_id"`
|
||||||
|
|
||||||
// OwnerId is the User's identifier for the current Provider.
|
// OwnerId is the User's identifier for the current Provider.
|
||||||
OwnerId HexaString `json:"_ownerid"`
|
OwnerId Identifier `json:"_ownerid"`
|
||||||
|
|
||||||
// Comment is a string that helps user to distinguish the Provider.
|
// Comment is a string that helps user to distinguish the Provider.
|
||||||
Comment string `json:"_comment,omitempty"`
|
Comment string `json:"_comment,omitempty"`
|
||||||
|
|
|
@ -57,10 +57,10 @@ type ServiceMeta struct {
|
||||||
Type string `json:"_svctype"`
|
Type string `json:"_svctype"`
|
||||||
|
|
||||||
// Id is the Service's identifier.
|
// Id is the Service's identifier.
|
||||||
Id HexaString `json:"_id,omitempty"`
|
Id Identifier `json:"_id,omitempty"`
|
||||||
|
|
||||||
// OwnerId is the User's identifier for the current Service.
|
// OwnerId is the User's identifier for the current Service.
|
||||||
OwnerId HexaString `json:"_ownerid,omitempty"`
|
OwnerId Identifier `json:"_ownerid,omitempty"`
|
||||||
|
|
||||||
// Domain contains the abstract domain where this Service relates.
|
// Domain contains the abstract domain where this Service relates.
|
||||||
Domain string `json:"_domain"`
|
Domain string `json:"_domain"`
|
||||||
|
|
|
@ -42,10 +42,10 @@ import (
|
||||||
// Session holds informatin about a User's currently connected.
|
// Session holds informatin about a User's currently connected.
|
||||||
type Session struct {
|
type Session struct {
|
||||||
// Id is the Session's identifier.
|
// Id is the Session's identifier.
|
||||||
Id []byte `json:"id"`
|
Id Identifier `json:"id"`
|
||||||
|
|
||||||
// IdUser is the User's identifier of the Session.
|
// IdUser is the User's identifier of the Session.
|
||||||
IdUser HexaString `json:"login"`
|
IdUser Identifier `json:"login"`
|
||||||
|
|
||||||
// IssuedAt holds the creation date of the Session.
|
// IssuedAt holds the creation date of the Session.
|
||||||
IssuedAt time.Time `json:"time"`
|
IssuedAt time.Time `json:"time"`
|
||||||
|
|
|
@ -63,10 +63,10 @@ type SourceMeta struct {
|
||||||
Type string `json:"_srctype"`
|
Type string `json:"_srctype"`
|
||||||
|
|
||||||
// Id is the Source's identifier.
|
// Id is the Source's identifier.
|
||||||
Id int64 `json:"_id"`
|
Id Identifier `json:"_id"`
|
||||||
|
|
||||||
// OwnerId is the User's identifier for the current Source.
|
// OwnerId is the User's identifier for the current Source.
|
||||||
OwnerId []byte `json:"_ownerid"`
|
OwnerId Identifier `json:"_ownerid"`
|
||||||
|
|
||||||
// Comment is a string that helps user to distinguish the Source.
|
// Comment is a string that helps user to distinguish the Source.
|
||||||
Comment string `json:"_comment,omitempty"`
|
Comment string `json:"_comment,omitempty"`
|
||||||
|
|
|
@ -38,7 +38,7 @@ import (
|
||||||
// User represents an account.
|
// User represents an account.
|
||||||
type User struct {
|
type User struct {
|
||||||
// Id is the User's identifier.
|
// Id is the User's identifier.
|
||||||
Id HexaString
|
Id Identifier
|
||||||
|
|
||||||
// Email is the User's login and mean of contact.
|
// Email is the User's login and mean of contact.
|
||||||
Email string
|
Email string
|
||||||
|
|
|
@ -46,7 +46,7 @@ import (
|
||||||
// UserAuth represents an account used for authentication (not used in case of external auth).
|
// UserAuth represents an account used for authentication (not used in case of external auth).
|
||||||
type UserAuth struct {
|
type UserAuth struct {
|
||||||
// Id is the User's identifier.
|
// Id is the User's identifier.
|
||||||
Id []byte
|
Id Identifier
|
||||||
|
|
||||||
// Email is the User's login and mean of contact.
|
// Email is the User's login and mean of contact.
|
||||||
Email string
|
Email string
|
||||||
|
|
|
@ -42,10 +42,10 @@ import (
|
||||||
// ZoneMeta holds the metadata associated to a Zone.
|
// ZoneMeta holds the metadata associated to a Zone.
|
||||||
type ZoneMeta struct {
|
type ZoneMeta struct {
|
||||||
// Id is the Zone's identifier.
|
// Id is the Zone's identifier.
|
||||||
Id int64 `json:"id"`
|
Id Identifier `json:"id"`
|
||||||
|
|
||||||
// IdAuthor is the User's identifier for the current Zone.
|
// IdAuthor is the User's identifier for the current Zone.
|
||||||
IdAuthor HexaString `json:"id_author"`
|
IdAuthor Identifier `json:"id_author"`
|
||||||
|
|
||||||
// DefaultTTL is the TTL to use when no TTL has been defined for a record in this Zone.
|
// DefaultTTL is the TTL to use when no TTL has been defined for a record in this Zone.
|
||||||
DefaultTTL uint32 `json:"default_ttl"`
|
DefaultTTL uint32 `json:"default_ttl"`
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -51,7 +51,7 @@ type Storage interface {
|
||||||
GetAuthUsers() (happydns.UserAuths, error)
|
GetAuthUsers() (happydns.UserAuths, error)
|
||||||
|
|
||||||
// GetAuthUser retrieves the User with the given identifier.
|
// GetAuthUser retrieves the User with the given identifier.
|
||||||
GetAuthUser(id []byte) (*happydns.UserAuth, error)
|
GetAuthUser(id happydns.Identifier) (*happydns.UserAuth, error)
|
||||||
|
|
||||||
// GetAuthUserByEmail retrives the User with the given email address.
|
// GetAuthUserByEmail retrives the User with the given email address.
|
||||||
GetAuthUserByEmail(email string) (*happydns.UserAuth, error)
|
GetAuthUserByEmail(email string) (*happydns.UserAuth, error)
|
||||||
|
@ -77,7 +77,7 @@ type Storage interface {
|
||||||
GetDomains(u *happydns.User) (happydns.Domains, error)
|
GetDomains(u *happydns.User) (happydns.Domains, error)
|
||||||
|
|
||||||
// GetDomain retrieves the Domain with the given id and owned by the given User.
|
// GetDomain retrieves the Domain with the given id and owned by the given User.
|
||||||
GetDomain(u *happydns.User, id int64) (*happydns.Domain, error)
|
GetDomain(u *happydns.User, id happydns.Identifier) (*happydns.Domain, error)
|
||||||
|
|
||||||
// GetDomainByDN is like GetDomain but look for the domain name instead of identifier.
|
// GetDomainByDN is like GetDomain but look for the domain name instead of identifier.
|
||||||
GetDomainByDN(u *happydns.User, dn string) (*happydns.Domain, error)
|
GetDomainByDN(u *happydns.User, dn string) (*happydns.Domain, error)
|
||||||
|
@ -106,10 +106,10 @@ type Storage interface {
|
||||||
GetProviderMetas(u *happydns.User) ([]happydns.ProviderMeta, error)
|
GetProviderMetas(u *happydns.User) ([]happydns.ProviderMeta, error)
|
||||||
|
|
||||||
// GetProviderMeta retrieves the metadatas for the Provider with the given identifier and owner.
|
// GetProviderMeta retrieves the metadatas for the Provider with the given identifier and owner.
|
||||||
GetProviderMeta(u *happydns.User, id int64) (*happydns.ProviderMeta, error)
|
GetProviderMeta(u *happydns.User, id happydns.Identifier) (*happydns.ProviderMeta, error)
|
||||||
|
|
||||||
// GetProvider retrieves the full Provider with the given identifier and owner.
|
// GetProvider retrieves the full Provider with the given identifier and owner.
|
||||||
GetProvider(u *happydns.User, id int64) (*happydns.ProviderCombined, error)
|
GetProvider(u *happydns.User, id happydns.Identifier) (*happydns.ProviderCombined, error)
|
||||||
|
|
||||||
// CreateProvider creates a record in the database for the given Provider.
|
// CreateProvider creates a record in the database for the given Provider.
|
||||||
CreateProvider(u *happydns.User, s happydns.Provider, comment string) (*happydns.ProviderCombined, error)
|
CreateProvider(u *happydns.User, s happydns.Provider, comment string) (*happydns.ProviderCombined, error)
|
||||||
|
@ -129,7 +129,7 @@ type Storage interface {
|
||||||
// SESSIONS ---------------------------------------------------
|
// SESSIONS ---------------------------------------------------
|
||||||
|
|
||||||
// GetSession retrieves the Session with the given identifier.
|
// GetSession retrieves the Session with the given identifier.
|
||||||
GetSession(id []byte) (*happydns.Session, error)
|
GetSession(id happydns.Identifier) (*happydns.Session, error)
|
||||||
|
|
||||||
// GetAuthUserSessions retrieves all Session for the given AuthUser.
|
// GetAuthUserSessions retrieves all Session for the given AuthUser.
|
||||||
GetAuthUserSessions(user *happydns.UserAuth) ([]*happydns.Session, error)
|
GetAuthUserSessions(user *happydns.UserAuth) ([]*happydns.Session, error)
|
||||||
|
@ -155,7 +155,7 @@ type Storage interface {
|
||||||
GetUsers() (happydns.Users, error)
|
GetUsers() (happydns.Users, error)
|
||||||
|
|
||||||
// GetUser retrieves the User with the given identifier.
|
// GetUser retrieves the User with the given identifier.
|
||||||
GetUser(id []byte) (*happydns.User, error)
|
GetUser(id happydns.Identifier) (*happydns.User, error)
|
||||||
|
|
||||||
// GetUserByEmail retrives the User with the given email address.
|
// GetUserByEmail retrives the User with the given email address.
|
||||||
GetUserByEmail(email string) (*happydns.User, error)
|
GetUserByEmail(email string) (*happydns.User, error)
|
||||||
|
@ -175,10 +175,10 @@ type Storage interface {
|
||||||
// ZONES ------------------------------------------------------
|
// ZONES ------------------------------------------------------
|
||||||
|
|
||||||
// GetZoneMeta retrives metadatas of the Zone with the given identifier.
|
// GetZoneMeta retrives metadatas of the Zone with the given identifier.
|
||||||
GetZoneMeta(id int64) (*happydns.ZoneMeta, error)
|
GetZoneMeta(id happydns.Identifier) (*happydns.ZoneMeta, error)
|
||||||
|
|
||||||
// GetZone retrieves the full Zone (including Services and metadatas) which have the given identifier.
|
// GetZone retrieves the full Zone (including Services and metadatas) which have the given identifier.
|
||||||
GetZone(id int64) (*happydns.Zone, error)
|
GetZone(id happydns.Identifier) (*happydns.Zone, error)
|
||||||
|
|
||||||
// CreateZone creates a record in the database for the given Zone.
|
// CreateZone creates a record in the database for the given Zone.
|
||||||
CreateZone(zone *happydns.Zone) error
|
CreateZone(zone *happydns.Zone) error
|
||||||
|
|
|
@ -62,9 +62,9 @@ func (s *LevelDBStorage) GetAuthUsers() (users happydns.UserAuths, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetAuthUser(id []byte) (u *happydns.UserAuth, err error) {
|
func (s *LevelDBStorage) GetAuthUser(id happydns.Identifier) (u *happydns.UserAuth, err error) {
|
||||||
u = &happydns.UserAuth{}
|
u = &happydns.UserAuth{}
|
||||||
err = s.get(fmt.Sprintf("auth-%x", id), &u)
|
err = s.get(fmt.Sprintf("auth-%s", id.String()), &u)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ func (s *LevelDBStorage) AuthUserExists(email string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) CreateAuthUser(u *happydns.UserAuth) error {
|
func (s *LevelDBStorage) CreateAuthUser(u *happydns.UserAuth) error {
|
||||||
key, id, err := s.findBytesKey("auth-", 16)
|
key, id, err := s.findIdentifierKey("auth-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,11 @@ func (s *LevelDBStorage) CreateAuthUser(u *happydns.UserAuth) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateAuthUser(u *happydns.UserAuth) error {
|
func (s *LevelDBStorage) UpdateAuthUser(u *happydns.UserAuth) error {
|
||||||
return s.put(fmt.Sprintf("auth-%x", u.Id), u)
|
return s.put(fmt.Sprintf("auth-%s", u.Id.String()), u)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) DeleteAuthUser(u *happydns.UserAuth) error {
|
func (s *LevelDBStorage) DeleteAuthUser(u *happydns.UserAuth) error {
|
||||||
return s.delete(fmt.Sprintf("auth-%x", u.Id))
|
return s.delete(fmt.Sprintf("auth-%s", u.Id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) ClearAuthUsers() error {
|
func (s *LevelDBStorage) ClearAuthUsers() error {
|
||||||
|
|
|
@ -32,11 +32,11 @@
|
||||||
package database // import "happydns.org/storage/leveldb"
|
package database // import "happydns.org/storage/leveldb"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
crand "crypto/rand"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
mrand "math/rand"
|
|
||||||
|
"git.happydns.org/happydomain/model"
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
|
@ -105,29 +105,14 @@ func (s *LevelDBStorage) put(key string, v interface{}) error {
|
||||||
return s.db.Put([]byte(key), data, nil)
|
return s.db.Put([]byte(key), data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) findInt63Key(prefix string) (key string, id int64, err error) {
|
func (s *LevelDBStorage) findIdentifierKey(prefix string) (key string, id happydns.Identifier, err error) {
|
||||||
found := true
|
found := true
|
||||||
for found {
|
for found {
|
||||||
// max random id is 2^53 to fit on float64 without loosing precision (JSON limitation)
|
id, err = happydns.NewRandomIdentifier()
|
||||||
id = mrand.Int63n(1 << 53)
|
|
||||||
key = fmt.Sprintf("%s%d", prefix, id)
|
|
||||||
|
|
||||||
found, err = s.db.Has([]byte(key), nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
key = fmt.Sprintf("%s%s", prefix, id.String())
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LevelDBStorage) findBytesKey(prefix string, len int) (key string, id []byte, err error) {
|
|
||||||
id = make([]byte, len)
|
|
||||||
found := true
|
|
||||||
for found {
|
|
||||||
if _, err = crand.Read(id); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
key = fmt.Sprintf("%s%x", prefix, id)
|
|
||||||
|
|
||||||
found, err = s.db.Has([]byte(key), nil)
|
found, err = s.db.Has([]byte(key), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -68,8 +68,8 @@ func (s *LevelDBStorage) getDomain(id string) (z *happydns.Domain, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetDomain(u *happydns.User, id int64) (z *happydns.Domain, err error) {
|
func (s *LevelDBStorage) GetDomain(u *happydns.User, id happydns.Identifier) (z *happydns.Domain, err error) {
|
||||||
z, err = s.getDomain(fmt.Sprintf("domain-%d", id))
|
z, err = s.getDomain(fmt.Sprintf("domain-%s", id.String()))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -119,7 +119,7 @@ func (s *LevelDBStorage) DomainExists(dn string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) CreateDomain(u *happydns.User, z *happydns.Domain) error {
|
func (s *LevelDBStorage) CreateDomain(u *happydns.User, z *happydns.Domain) error {
|
||||||
key, id, err := s.findInt63Key("domain-")
|
key, id, err := s.findIdentifierKey("domain-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -130,16 +130,16 @@ func (s *LevelDBStorage) CreateDomain(u *happydns.User, z *happydns.Domain) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateDomain(z *happydns.Domain) error {
|
func (s *LevelDBStorage) UpdateDomain(z *happydns.Domain) error {
|
||||||
return s.put(fmt.Sprintf("domain-%d", z.Id), z)
|
return s.put(fmt.Sprintf("domain-%s", z.Id.String()), z)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateDomainOwner(z *happydns.Domain, newOwner *happydns.User) error {
|
func (s *LevelDBStorage) UpdateDomainOwner(z *happydns.Domain, newOwner *happydns.User) error {
|
||||||
z.IdUser = newOwner.Id
|
z.IdUser = newOwner.Id
|
||||||
return s.put(fmt.Sprintf("domain-%d", z.Id), z)
|
return s.put(fmt.Sprintf("domain-%s", z.Id.String()), z)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) DeleteDomain(z *happydns.Domain) error {
|
func (s *LevelDBStorage) DeleteDomain(z *happydns.Domain) error {
|
||||||
return s.delete(fmt.Sprintf("domain-%d", z.Id))
|
return s.delete(fmt.Sprintf("domain-%s", z.Id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) ClearDomains() error {
|
func (s *LevelDBStorage) ClearDomains() error {
|
||||||
|
@ -191,18 +191,18 @@ func (s *LevelDBStorage) TidyDomains() error {
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
// Drop domain of unexistant users
|
// Drop domain of unexistant users
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
log.Printf("Deleting orphan domain (user %d not found): %v\n", domain.IdUser, domain)
|
log.Printf("Deleting orphan domain (user %s not found): %v\n", domain.IdUser.String(), domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.GetProvider(u, domain.IdProvider)
|
_, err = s.GetProvider(u, domain.IdProvider)
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
// Drop domain of unexistant provider
|
// Drop domain of unexistant provider
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
log.Printf("Deleting orphan domain (provider %d not found): %v\n", domain.IdProvider, domain)
|
log.Printf("Deleting orphan domain (provider %s not found): %v\n", domain.IdProvider.String(), domain)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Drop unreadable domains
|
// Drop unreadable domains
|
||||||
log.Printf("Deleting unreadable domain (%w): %v\n", err, domain)
|
log.Printf("Deleting unreadable domain (%s): %v\n", err.Error(), domain)
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ import (
|
||||||
"git.happydns.org/happydomain/providers"
|
"git.happydns.org/happydomain/providers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *LevelDBStorage) getProviderMeta(id []byte) (srcMeta *happydns.ProviderMeta, err error) {
|
func (s *LevelDBStorage) getProviderMeta(id happydns.Identifier) (srcMeta *happydns.ProviderMeta, err error) {
|
||||||
var v []byte
|
var v []byte
|
||||||
v, err = s.db.Get(id, nil)
|
v, err = s.db.Get(id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,9 +77,9 @@ func (s *LevelDBStorage) GetProviderMetas(u *happydns.User) (srcs []happydns.Pro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetProviderMeta(u *happydns.User, id int64) (srcMeta *happydns.ProviderMeta, err error) {
|
func (s *LevelDBStorage) GetProviderMeta(u *happydns.User, id happydns.Identifier) (srcMeta *happydns.ProviderMeta, err error) {
|
||||||
var v []byte
|
var v []byte
|
||||||
v, err = s.db.Get([]byte(fmt.Sprintf("provider-%d", id)), nil)
|
v, err = s.db.Get([]byte(fmt.Sprintf("provider-%s", id.String())), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -98,9 +98,9 @@ func (s *LevelDBStorage) GetProviderMeta(u *happydns.User, id int64) (srcMeta *h
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetProvider(u *happydns.User, id int64) (src *happydns.ProviderCombined, err error) {
|
func (s *LevelDBStorage) GetProvider(u *happydns.User, id happydns.Identifier) (src *happydns.ProviderCombined, err error) {
|
||||||
var v []byte
|
var v []byte
|
||||||
v, err = s.db.Get([]byte(fmt.Sprintf("provider-%d", id)), nil)
|
v, err = s.db.Get([]byte(fmt.Sprintf("provider-%s", id.String())), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ func (s *LevelDBStorage) GetProvider(u *happydns.User, id int64) (src *happydns.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) CreateProvider(u *happydns.User, src happydns.Provider, comment string) (*happydns.ProviderCombined, error) {
|
func (s *LevelDBStorage) CreateProvider(u *happydns.User, src happydns.Provider, comment string) (*happydns.ProviderCombined, error) {
|
||||||
key, id, err := s.findInt63Key("provider-")
|
key, id, err := s.findIdentifierKey("provider-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ func (s *LevelDBStorage) CreateProvider(u *happydns.User, src happydns.Provider,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateProvider(src *happydns.ProviderCombined) error {
|
func (s *LevelDBStorage) UpdateProvider(src *happydns.ProviderCombined) error {
|
||||||
return s.put(fmt.Sprintf("provider-%d", src.Id), src)
|
return s.put(fmt.Sprintf("provider-%s", src.Id.String()), src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateProviderOwner(src *happydns.ProviderCombined, newOwner *happydns.User) error {
|
func (s *LevelDBStorage) UpdateProviderOwner(src *happydns.ProviderCombined, newOwner *happydns.User) error {
|
||||||
|
@ -159,7 +159,7 @@ func (s *LevelDBStorage) UpdateProviderOwner(src *happydns.ProviderCombined, new
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) DeleteProvider(src *happydns.ProviderMeta) error {
|
func (s *LevelDBStorage) DeleteProvider(src *happydns.ProviderMeta) error {
|
||||||
return s.delete(fmt.Sprintf("provider-%d", src.Id))
|
return s.delete(fmt.Sprintf("provider-%s", src.Id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) ClearProviders() error {
|
func (s *LevelDBStorage) ClearProviders() error {
|
||||||
|
@ -202,13 +202,13 @@ func (s *LevelDBStorage) TidyProviders() error {
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Drop unreadable providers
|
// Drop unreadable providers
|
||||||
log.Printf("Deleting unreadable provider (%w): %v\n", err, srcMeta)
|
log.Printf("Deleting unreadable provider (%s): %v\n", err.Error(), srcMeta)
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
} else {
|
} else {
|
||||||
_, err = s.GetUser(srcMeta.OwnerId)
|
_, err = s.GetUser(srcMeta.OwnerId)
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
// Drop providers of unexistant users
|
// Drop providers of unexistant users
|
||||||
log.Printf("Deleting orphan provider (user %d not found): %v\n", srcMeta.OwnerId, srcMeta)
|
log.Printf("Deleting orphan provider (user %s not found): %v\n", srcMeta.OwnerId.String(), srcMeta)
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,8 @@ func (s *LevelDBStorage) getSession(id string) (session *happydns.Session, err e
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetSession(id []byte) (session *happydns.Session, err error) {
|
func (s *LevelDBStorage) GetSession(id happydns.Identifier) (session *happydns.Session, err error) {
|
||||||
return s.getSession(fmt.Sprintf("user.session-%x", id))
|
return s.getSession(fmt.Sprintf("user.session-%s", id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetAuthUserSessions(user *happydns.UserAuth) (sessions []*happydns.Session, err error) {
|
func (s *LevelDBStorage) GetAuthUserSessions(user *happydns.UserAuth) (sessions []*happydns.Session, err error) {
|
||||||
|
@ -86,7 +86,7 @@ func (s *LevelDBStorage) GetUserSessions(user *happydns.User) (sessions []*happy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) CreateSession(session *happydns.Session) error {
|
func (s *LevelDBStorage) CreateSession(session *happydns.Session) error {
|
||||||
key, id, err := s.findBytesKey("user.session-", 16)
|
key, id, err := s.findIdentifierKey("user.session-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -97,11 +97,11 @@ func (s *LevelDBStorage) CreateSession(session *happydns.Session) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateSession(session *happydns.Session) error {
|
func (s *LevelDBStorage) UpdateSession(session *happydns.Session) error {
|
||||||
return s.put(fmt.Sprintf("user.session-%x", session.Id), session)
|
return s.put(fmt.Sprintf("user.session-%s", session.Id.String()), session)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) DeleteSession(session *happydns.Session) error {
|
func (s *LevelDBStorage) DeleteSession(session *happydns.Session) error {
|
||||||
return s.delete(fmt.Sprintf("user.session-%x", session.Id))
|
return s.delete(fmt.Sprintf("user.session-%s", session.Id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) ClearSessions() error {
|
func (s *LevelDBStorage) ClearSessions() error {
|
||||||
|
@ -144,13 +144,13 @@ func (s *LevelDBStorage) TidySessions() error {
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Drop unreadable sessions
|
// Drop unreadable sessions
|
||||||
log.Printf("Deleting unreadable session (%w): %v\n", err, session)
|
log.Printf("Deleting unreadable session (%s): %v\n", err.Error(), session)
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
} else {
|
} else {
|
||||||
_, err = s.GetUser(session.IdUser)
|
_, err = s.GetUser(session.IdUser)
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
// Drop session from unexistant users
|
// Drop session from unexistant users
|
||||||
log.Printf("Deleting orphan session (user %d not found): %v\n", session.IdUser, session)
|
log.Printf("Deleting orphan session (user %s not found): %v\n", session.IdUser.String(), session)
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,9 @@ func (s *LevelDBStorage) GetUsers() (users happydns.Users, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetUser(id []byte) (u *happydns.User, err error) {
|
func (s *LevelDBStorage) GetUser(id happydns.Identifier) (u *happydns.User, err error) {
|
||||||
u = &happydns.User{}
|
u = &happydns.User{}
|
||||||
err = s.get(fmt.Sprintf("user-%x", id), &u)
|
err = s.get(fmt.Sprintf("user-%s", id.String()), &u)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ func (s *LevelDBStorage) UserExists(email string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) CreateUser(u *happydns.User) error {
|
func (s *LevelDBStorage) CreateUser(u *happydns.User) error {
|
||||||
key, id, err := s.findBytesKey("user-", 16)
|
key, id, err := s.findIdentifierKey("user-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,11 @@ func (s *LevelDBStorage) CreateUser(u *happydns.User) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateUser(u *happydns.User) error {
|
func (s *LevelDBStorage) UpdateUser(u *happydns.User) error {
|
||||||
return s.put(fmt.Sprintf("user-%x", u.Id), u)
|
return s.put(fmt.Sprintf("user-%s", u.Id.String()), u)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) DeleteUser(u *happydns.User) error {
|
func (s *LevelDBStorage) DeleteUser(u *happydns.User) error {
|
||||||
return s.delete(fmt.Sprintf("user-%x", u.Id))
|
return s.delete(fmt.Sprintf("user-%s", u.Id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) ClearUsers() error {
|
func (s *LevelDBStorage) ClearUsers() error {
|
||||||
|
|
|
@ -34,7 +34,6 @@ package database
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.happydns.org/happydomain/model"
|
"git.happydns.org/happydomain/model"
|
||||||
|
@ -42,9 +41,9 @@ import (
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetZone(id int64) (z *happydns.Zone, err error) {
|
func (s *LevelDBStorage) GetZone(id happydns.Identifier) (z *happydns.Zone, err error) {
|
||||||
z = &happydns.Zone{}
|
z = &happydns.Zone{}
|
||||||
err = s.get(fmt.Sprintf("domain.zone-%d", id), &z)
|
err = s.get(fmt.Sprintf("domain.zone-%s", id.String()), &z)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,13 +53,13 @@ func (s *LevelDBStorage) getZoneMeta(id string) (z *happydns.ZoneMeta, err error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) GetZoneMeta(id int64) (z *happydns.ZoneMeta, err error) {
|
func (s *LevelDBStorage) GetZoneMeta(id happydns.Identifier) (z *happydns.ZoneMeta, err error) {
|
||||||
z, err = s.getZoneMeta(fmt.Sprintf("domain.zone-%d", id))
|
z, err = s.getZoneMeta(fmt.Sprintf("domain.zone-%s", id.String()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) CreateZone(z *happydns.Zone) error {
|
func (s *LevelDBStorage) CreateZone(z *happydns.Zone) error {
|
||||||
key, id, err := s.findInt63Key("domain.zone-")
|
key, id, err := s.findIdentifierKey("domain.zone-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -70,11 +69,11 @@ func (s *LevelDBStorage) CreateZone(z *happydns.Zone) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) UpdateZone(z *happydns.Zone) error {
|
func (s *LevelDBStorage) UpdateZone(z *happydns.Zone) error {
|
||||||
return s.put(fmt.Sprintf("domain.zone-%d", z.Id), z)
|
return s.put(fmt.Sprintf("domain.zone-%s", z.Id.String()), z)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) DeleteZone(z *happydns.Zone) error {
|
func (s *LevelDBStorage) DeleteZone(z *happydns.Zone) error {
|
||||||
return s.delete(fmt.Sprintf("domain.zone-%d", z.Id))
|
return s.delete(fmt.Sprintf("domain.zone-%s", z.Id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LevelDBStorage) ClearZones() error {
|
func (s *LevelDBStorage) ClearZones() error {
|
||||||
|
@ -112,7 +111,7 @@ func (s *LevelDBStorage) TidyZones() error {
|
||||||
iter := tx.NewIterator(util.BytesPrefix([]byte("domain-")), nil)
|
iter := tx.NewIterator(util.BytesPrefix([]byte("domain-")), nil)
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
|
|
||||||
var referencedZones []int64
|
var referencedZones []happydns.Identifier
|
||||||
|
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
domain, _ := s.getDomain(string(iter.Key()))
|
domain, _ := s.getDomain(string(iter.Key()))
|
||||||
|
@ -128,14 +127,14 @@ func (s *LevelDBStorage) TidyZones() error {
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
|
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
if zoneId, err := strconv.ParseInt(strings.TrimPrefix(string(iter.Key()), "domain.zone-"), 10, 64); err != nil {
|
if zoneId, err := happydns.NewIdentifierFromString(strings.TrimPrefix(string(iter.Key()), "domain.zone-")); err != nil {
|
||||||
// Drop zones with invalid ID
|
// Drop zones with invalid ID
|
||||||
log.Printf("Deleting unindentified zone: key=%s\n", iter.Key())
|
log.Printf("Deleting unindentified zone: key=%s\n", iter.Key())
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
} else {
|
} else {
|
||||||
foundZone := false
|
foundZone := false
|
||||||
for _, zid := range referencedZones {
|
for _, zid := range referencedZones {
|
||||||
if zid == zoneId {
|
if zid.Equals(zoneId) {
|
||||||
foundZone = true
|
foundZone = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -143,7 +142,7 @@ func (s *LevelDBStorage) TidyZones() error {
|
||||||
|
|
||||||
if !foundZone {
|
if !foundZone {
|
||||||
// Drop orphan zones
|
// Drop orphan zones
|
||||||
log.Printf("Deleting orphan zone: %d\n", zoneId)
|
log.Printf("Deleting orphan zone: %s\n", zoneId.String())
|
||||||
err = tx.Delete(iter.Key(), nil)
|
err = tx.Delete(iter.Key(), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue