github.com/edxfund/validator@v1.8.16-0.20181020093046-c1def72855da/cmd/swarm/access.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  package main
    17  
    18  import (
    19  	"crypto/rand"
    20  	"encoding/json"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"strings"
    25  
    26  	"github.com/EDXFund/Validator/cmd/utils"
    27  	"github.com/EDXFund/Validator/swarm/api"
    28  	"github.com/EDXFund/Validator/swarm/api/client"
    29  	"gopkg.in/urfave/cli.v1"
    30  )
    31  
    32  var salt = make([]byte, 32)
    33  
    34  func init() {
    35  	if _, err := io.ReadFull(rand.Reader, salt); err != nil {
    36  		panic("reading from crypto/rand failed: " + err.Error())
    37  	}
    38  }
    39  
    40  func accessNewPass(ctx *cli.Context) {
    41  	args := ctx.Args()
    42  	if len(args) != 1 {
    43  		utils.Fatalf("Expected 1 argument - the ref")
    44  	}
    45  
    46  	var (
    47  		ae        *api.AccessEntry
    48  		accessKey []byte
    49  		err       error
    50  		ref       = args[0]
    51  		password  = getPassPhrase("", 0, makePasswordList(ctx))
    52  		dryRun    = ctx.Bool(SwarmDryRunFlag.Name)
    53  	)
    54  	accessKey, ae, err = api.DoPassword(ctx, password, salt)
    55  	if err != nil {
    56  		utils.Fatalf("error getting session key: %v", err)
    57  	}
    58  	m, err := api.GenerateAccessControlManifest(ctx, ref, accessKey, ae)
    59  	if dryRun {
    60  		err = printManifests(m, nil)
    61  		if err != nil {
    62  			utils.Fatalf("had an error printing the manifests: %v", err)
    63  		}
    64  	} else {
    65  		utils.Fatalf("uploading manifests")
    66  		err = uploadManifests(ctx, m, nil)
    67  		if err != nil {
    68  			utils.Fatalf("had an error uploading the manifests: %v", err)
    69  		}
    70  	}
    71  }
    72  
    73  func accessNewPK(ctx *cli.Context) {
    74  	args := ctx.Args()
    75  	if len(args) != 1 {
    76  		utils.Fatalf("Expected 1 argument - the ref")
    77  	}
    78  
    79  	var (
    80  		ae               *api.AccessEntry
    81  		sessionKey       []byte
    82  		err              error
    83  		ref              = args[0]
    84  		privateKey       = getPrivKey(ctx)
    85  		granteePublicKey = ctx.String(SwarmAccessGrantKeyFlag.Name)
    86  		dryRun           = ctx.Bool(SwarmDryRunFlag.Name)
    87  	)
    88  	sessionKey, ae, err = api.DoPK(ctx, privateKey, granteePublicKey, salt)
    89  	if err != nil {
    90  		utils.Fatalf("error getting session key: %v", err)
    91  	}
    92  	m, err := api.GenerateAccessControlManifest(ctx, ref, sessionKey, ae)
    93  	if dryRun {
    94  		err = printManifests(m, nil)
    95  		if err != nil {
    96  			utils.Fatalf("had an error printing the manifests: %v", err)
    97  		}
    98  	} else {
    99  		err = uploadManifests(ctx, m, nil)
   100  		if err != nil {
   101  			utils.Fatalf("had an error uploading the manifests: %v", err)
   102  		}
   103  	}
   104  }
   105  
   106  func accessNewACT(ctx *cli.Context) {
   107  	args := ctx.Args()
   108  	if len(args) != 1 {
   109  		utils.Fatalf("Expected 1 argument - the ref")
   110  	}
   111  
   112  	var (
   113  		ae                   *api.AccessEntry
   114  		actManifest          *api.Manifest
   115  		accessKey            []byte
   116  		err                  error
   117  		ref                  = args[0]
   118  		pkGrantees           = []string{}
   119  		passGrantees         = []string{}
   120  		pkGranteesFilename   = ctx.String(SwarmAccessGrantKeysFlag.Name)
   121  		passGranteesFilename = ctx.String(utils.PasswordFileFlag.Name)
   122  		privateKey           = getPrivKey(ctx)
   123  		dryRun               = ctx.Bool(SwarmDryRunFlag.Name)
   124  	)
   125  	if pkGranteesFilename == "" && passGranteesFilename == "" {
   126  		utils.Fatalf("you have to provide either a grantee public-keys file or an encryption passwords file (or both)")
   127  	}
   128  
   129  	if pkGranteesFilename != "" {
   130  		bytes, err := ioutil.ReadFile(pkGranteesFilename)
   131  		if err != nil {
   132  			utils.Fatalf("had an error reading the grantee public key list")
   133  		}
   134  		pkGrantees = strings.Split(string(bytes), "\n")
   135  	}
   136  
   137  	if passGranteesFilename != "" {
   138  		bytes, err := ioutil.ReadFile(passGranteesFilename)
   139  		if err != nil {
   140  			utils.Fatalf("could not read password filename: %v", err)
   141  		}
   142  		passGrantees = strings.Split(string(bytes), "\n")
   143  	}
   144  	accessKey, ae, actManifest, err = api.DoACT(ctx, privateKey, salt, pkGrantees, passGrantees)
   145  	if err != nil {
   146  		utils.Fatalf("error generating ACT manifest: %v", err)
   147  	}
   148  
   149  	if err != nil {
   150  		utils.Fatalf("error getting session key: %v", err)
   151  	}
   152  	m, err := api.GenerateAccessControlManifest(ctx, ref, accessKey, ae)
   153  	if err != nil {
   154  		utils.Fatalf("error generating root access manifest: %v", err)
   155  	}
   156  
   157  	if dryRun {
   158  		err = printManifests(m, actManifest)
   159  		if err != nil {
   160  			utils.Fatalf("had an error printing the manifests: %v", err)
   161  		}
   162  	} else {
   163  		err = uploadManifests(ctx, m, actManifest)
   164  		if err != nil {
   165  			utils.Fatalf("had an error uploading the manifests: %v", err)
   166  		}
   167  	}
   168  }
   169  
   170  func printManifests(rootAccessManifest, actManifest *api.Manifest) error {
   171  	js, err := json.Marshal(rootAccessManifest)
   172  	if err != nil {
   173  		return err
   174  	}
   175  	fmt.Println(string(js))
   176  
   177  	if actManifest != nil {
   178  		js, err := json.Marshal(actManifest)
   179  		if err != nil {
   180  			return err
   181  		}
   182  		fmt.Println(string(js))
   183  	}
   184  	return nil
   185  }
   186  
   187  func uploadManifests(ctx *cli.Context, rootAccessManifest, actManifest *api.Manifest) error {
   188  	bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
   189  	client := client.NewClient(bzzapi)
   190  
   191  	var (
   192  		key string
   193  		err error
   194  	)
   195  	if actManifest != nil {
   196  		key, err = client.UploadManifest(actManifest, false)
   197  		if err != nil {
   198  			return err
   199  		}
   200  
   201  		rootAccessManifest.Entries[0].Access.Act = key
   202  	}
   203  	key, err = client.UploadManifest(rootAccessManifest, false)
   204  	if err != nil {
   205  		return err
   206  	}
   207  	fmt.Println(key)
   208  	return nil
   209  }
   210  
   211  // makePasswordList reads password lines from the file specified by the global --password flag
   212  // and also by the same subcommand --password flag.
   213  // This function ia a fork of utils.MakePasswordList to lookup cli context for subcommand.
   214  // Function ctx.SetGlobal is not setting the global flag value that can be accessed
   215  // by ctx.GlobalString using the current version of cli package.
   216  func makePasswordList(ctx *cli.Context) []string {
   217  	path := ctx.GlobalString(utils.PasswordFileFlag.Name)
   218  	if path == "" {
   219  		path = ctx.String(utils.PasswordFileFlag.Name)
   220  		if path == "" {
   221  			return nil
   222  		}
   223  	}
   224  	text, err := ioutil.ReadFile(path)
   225  	if err != nil {
   226  		utils.Fatalf("Failed to read password file: %v", err)
   227  	}
   228  	lines := strings.Split(string(text), "\n")
   229  	// Sanitise DOS line endings.
   230  	for i := range lines {
   231  		lines[i] = strings.TrimRight(lines[i], "\r")
   232  	}
   233  	return lines
   234  }