github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/docs/iam/access-manager-plugin.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  // Copyright (c) 2015-2022 MinIO, Inc.
     5  //
     6  // This file is part of MinIO Object Storage stack
     7  //
     8  // This program is free software: you can redistribute it and/or modify
     9  // it under the terms of the GNU Affero General Public License as published by
    10  // the Free Software Foundation, either version 3 of the License, or
    11  // (at your option) any later version.
    12  //
    13  // This program is distributed in the hope that it will be useful
    14  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  // GNU Affero General Public License for more details.
    17  //
    18  // You should have received a copy of the GNU Affero General Public License
    19  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20  
    21  package main
    22  
    23  import (
    24  	"bytes"
    25  	"encoding/json"
    26  	"flag"
    27  	"fmt"
    28  	"io"
    29  	"log"
    30  	"net/http"
    31  	"strings"
    32  )
    33  
    34  var (
    35  	keyFile  string
    36  	certFile string
    37  )
    38  
    39  func init() {
    40  	flag.StringVar(&keyFile, "key-file", "", "Path to TLS cert key file")
    41  	flag.StringVar(&certFile, "cert-file", "", "Path to TLS cert file")
    42  }
    43  
    44  func writeErrorResponse(w http.ResponseWriter, err error) {
    45  	w.WriteHeader(http.StatusBadRequest)
    46  	json.NewEncoder(w).Encode(map[string]string{
    47  		"error": fmt.Sprintf("%v", err),
    48  	})
    49  }
    50  
    51  type Result struct {
    52  	Result bool `json:"result"`
    53  }
    54  
    55  func mainHandler(w http.ResponseWriter, r *http.Request) {
    56  	body, err := io.ReadAll(r.Body)
    57  	if err != nil {
    58  		writeErrorResponse(w, err)
    59  		return
    60  	}
    61  
    62  	var out bytes.Buffer
    63  	json.Indent(&out, body, "", "  ")
    64  	fmt.Printf("Received JSON payload:\n%s\n", out.String())
    65  
    66  	reqMap := make(map[string]interface{})
    67  	err = json.Unmarshal(body, &reqMap)
    68  	if err != nil {
    69  		writeErrorResponse(w, err)
    70  		return
    71  	}
    72  
    73  	m := reqMap["input"].(map[string]interface{})
    74  	accountValue := m["account"].(string)
    75  	actionValue := m["action"].(string)
    76  
    77  	// Allow user `minio` to perform any action.
    78  	var res Result
    79  	if accountValue == "minio" {
    80  		res.Result = true
    81  	} else {
    82  		// All other users may not perform any `s3:Put*` operations.
    83  		res.Result = true
    84  		if strings.HasPrefix(actionValue, "s3:Put") {
    85  			res.Result = false
    86  		}
    87  	}
    88  	fmt.Printf("account: %v | action: %v | allowed: %v\n", accountValue, actionValue, res.Result)
    89  	json.NewEncoder(w).Encode(res)
    90  	return
    91  }
    92  
    93  func main() {
    94  	flag.Parse()
    95  	serveFunc := func() error {
    96  		return http.ListenAndServe(":8080", nil)
    97  	}
    98  
    99  	if certFile != "" || keyFile != "" {
   100  		if certFile == "" || keyFile == "" {
   101  			log.Fatal("Please provide both a key file and a cert file to enable TLS.")
   102  		}
   103  		serveFunc = func() error {
   104  			return http.ListenAndServeTLS(":8080", certFile, keyFile, nil)
   105  		}
   106  	}
   107  
   108  	http.HandleFunc("/", mainHandler)
   109  
   110  	log.Print("Listening on :8080")
   111  	log.Fatal(serveFunc())
   112  }