Geen omschrijving

account.go 6.8KB

    package account import ( "encoding/json" "errors" "fmt" "io/ioutil" "os" "path/filepath" "strings" "time" "code.revolvingcow.com/revolvingcow/loop/environment" "code.revolvingcow.com/revolvingcow/loop/security" ) const ( UserFile = "loop_users" PublishDateLayout = "200601021504" ) type Account struct { Username string `json:username` Passphrase string `json:passphrase` } func getAccounts() ([]Account, error) { file := UserFile // Check to see if the file exists if _, err := os.Stat(file); os.IsNotExist(err) { return []Account{}, nil } // Open the file fi, err := os.Open(file) if err != nil { return nil, err } // Read all of its contents raw, err := ioutil.ReadAll(fi) if len(raw) == 0 { return []Account{}, nil } // Translate the JSON to internal structures var accounts []Account err = json.Unmarshal(raw, &accounts) if err != nil { return nil, err } fi.Close() return accounts, nil } func (a *Account) Validate() (bool, error) { file := UserFile // Determine if the "users" file exists // Attempt to create the file if it does not if _, err := os.Stat(file); os.IsNotExist(err) { _, err = os.Create(file) if err != nil { return false, err } } // Get a list of current accounts accounts, err := getAccounts() if err != nil { return false, err } // Search if an account and passphrase match is found for _, x := range accounts { if x.Username == a.Username && x.Passphrase == a.Passphrase { return true, nil } } return false, nil } func (a *Account) Create() error { // Ensure there are no accounts of that name already valid, err := a.Validate() if err != nil { return err } if valid { return errors.New("Account already exists") } // Create directory structure baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) paths := []string{"content", "blog", "calendar"} for _, p := range paths { err = os.MkdirAll(baseDir+s+userDir+s+p, 0755) if err != nil { return err } } // Add the account to all of the accounts accounts, err := getAccounts() if err != nil { return err } accounts = append(accounts, *a) // Create user entry in "users" file // Marshal the JSON marshalled, err := json.Marshal(accounts) if err != nil { return err } // Write to the file fi, err := os.OpenFile(UserFile, os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { return err } _, err = fi.Write(marshalled) if err != nil { return err } fi.Close() return nil } func (a *Account) Delete() error { // Ensure there are no accounts of that name already valid, err := a.Validate() if err != nil { return err } if !valid { return errors.New("Account does not exist") } // Remove user entry in "users" file accounts, err := getAccounts() if err != nil { return err } for i, account := range accounts { if account.Username == a.Username { accounts = append(accounts[:i], accounts[i+1:]...) break } } marshalled, err := json.Marshal(accounts) if err != nil { return err } // Write to the file fi, err := os.OpenFile(UserFile, os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { return err } _, err = fi.Write(marshalled) if err != nil { return err } fi.Close() // Delete directory structure baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) err = os.RemoveAll(baseDir + s + userDir) if err != nil { return err } return nil } func (a *Account) Add(content, filename string, file []byte) (string, error) { if filename == "" { return "", errors.New("Missing filename") } valid, err := a.Validate() if err != nil { return "", err } if !valid { return "", errors.New("Account does not exist") } // Get basic information needed baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) // Create new content directory if necessary if content == "" { content = fmt.Sprintf("%x", security.Hash(userDir+time.Now().Format(PublishDateLayout), environment.Salt())) } // Create new content directory contentPath := baseDir + s + userDir + s + "content" + s + content if _, err := os.Stat(contentPath); os.IsNotExist(err) { err = os.MkdirAll(contentPath, 0755) if err != nil { return "", err } } // Check if filename already exists filePath := contentPath + s + filename //if _, err := os.Stat(filePath); os.IsExist(err) { // return filePath, err //} // Write file to content directory fi, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { return filePath, err } _, err = fi.Write(file) if err != nil { return filePath, err } fi.Close() return filePath, nil } func (a *Account) Publish(title, content string, date time.Time) error { valid, err := a.Validate() if err != nil { return err } if !valid { return errors.New("Account does not exist") } prettyTitle := strings.ToLower(strings.Replace(title, " ", "-", -1)) baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) contentPath := baseDir + s + userDir + s + "content" + s + content publishPath := baseDir + s + userDir + s + "blog" + s + date.Format(PublishDateLayout) + "-" + prettyTitle // Check if the content exists if _, err := os.Stat(contentPath); os.IsNotExist(err) { return err } // Check if symlink already exists if _, err := os.Stat(publishPath); os.IsExist(err) { return err } // Create symbolic link in "blog" directory referencing content directory err = os.Symlink(contentPath, publishPath) if err != nil { return err } return nil } func (a *Account) Content() ([]string, error) { baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) contentPath := baseDir + s + userDir + s + "content" d, err := os.Open(contentPath) if err != nil { return []string{}, err } return d.Readdirnames(0) } func (a *Account) Read(title string) (string, error) { baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) fp := baseDir + s + userDir + s + "content" + s + title + s + "document.md" // Check to see if the file exists if _, err := os.Stat(fp); os.IsNotExist(err) { return "", err } // Open the file fi, err := os.Open(fp) if err != nil { return "", err } // Read all of its contents raw, err := ioutil.ReadAll(fi) if err != nil { return "", err } return string(raw), nil } func (a *Account) Remove(title string) error { baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) fp := baseDir + s + userDir + s + "content" + s + title // Check to see if the file exists if _, err := os.Stat(fp); os.IsNotExist(err) { return err } // Delete the directory return os.RemoveAll(fp) }