github.com/cs3org/reva/v2@v2.27.7/pkg/siteacc/siteacc.go (about)

     1  // Copyright 2018-2021 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package siteacc
    20  
    21  import (
    22  	"fmt"
    23  	"net/http"
    24  
    25  	accpanel "github.com/cs3org/reva/v2/pkg/siteacc/account"
    26  	"github.com/cs3org/reva/v2/pkg/siteacc/admin"
    27  	"github.com/cs3org/reva/v2/pkg/siteacc/alerting"
    28  	"github.com/cs3org/reva/v2/pkg/siteacc/config"
    29  	"github.com/cs3org/reva/v2/pkg/siteacc/data"
    30  	"github.com/cs3org/reva/v2/pkg/siteacc/html"
    31  	"github.com/cs3org/reva/v2/pkg/siteacc/manager"
    32  	"github.com/pkg/errors"
    33  	"github.com/rs/zerolog"
    34  )
    35  
    36  // SiteAccounts represents the main Site Accounts service object.
    37  type SiteAccounts struct {
    38  	conf *config.Configuration
    39  	log  *zerolog.Logger
    40  
    41  	sessions *html.SessionManager
    42  
    43  	storage data.Storage
    44  
    45  	sitesManager    *manager.SitesManager
    46  	accountsManager *manager.AccountsManager
    47  	usersManager    *manager.UsersManager
    48  
    49  	alertsDispatcher *alerting.Dispatcher
    50  
    51  	adminPanel   *admin.Panel
    52  	accountPanel *accpanel.Panel
    53  }
    54  
    55  func (siteacc *SiteAccounts) initialize(conf *config.Configuration, log *zerolog.Logger) error {
    56  	if conf == nil {
    57  		return fmt.Errorf("no configuration provided")
    58  	}
    59  	siteacc.conf = conf
    60  
    61  	if log == nil {
    62  		return fmt.Errorf("no logger provided")
    63  	}
    64  	siteacc.log = log
    65  
    66  	// Create the session mananger
    67  	sessions, err := html.NewSessionManager("siteacc_session", conf, log)
    68  	if err != nil {
    69  		return errors.Wrap(err, "error while creating the session manager")
    70  	}
    71  	siteacc.sessions = sessions
    72  
    73  	// Create the central storage
    74  	storage, err := siteacc.createStorage(conf.Storage.Driver)
    75  	if err != nil {
    76  		return errors.Wrap(err, "unable to create storage")
    77  	}
    78  	siteacc.storage = storage
    79  
    80  	// Create the sites manager instance
    81  	smngr, err := manager.NewSitesManager(storage, conf, log)
    82  	if err != nil {
    83  		return errors.Wrap(err, "error creating the sites manager")
    84  	}
    85  	siteacc.sitesManager = smngr
    86  
    87  	// Create the accounts manager instance
    88  	amngr, err := manager.NewAccountsManager(storage, conf, log)
    89  	if err != nil {
    90  		return errors.Wrap(err, "error creating the accounts manager")
    91  	}
    92  	siteacc.accountsManager = amngr
    93  
    94  	// Create the users manager instance
    95  	umngr, err := manager.NewUsersManager(conf, log, siteacc.sitesManager, siteacc.accountsManager)
    96  	if err != nil {
    97  		return errors.Wrap(err, "error creating the users manager")
    98  	}
    99  	siteacc.usersManager = umngr
   100  
   101  	// Create the alerts dispatcher instance
   102  	dispatcher, err := alerting.NewDispatcher(conf, log)
   103  	if err != nil {
   104  		return errors.Wrap(err, "error creating the alerts dispatcher")
   105  	}
   106  	siteacc.alertsDispatcher = dispatcher
   107  
   108  	// Create the admin panel
   109  	if pnl, err := admin.NewPanel(conf, log); err == nil {
   110  		siteacc.adminPanel = pnl
   111  	} else {
   112  		return errors.Wrap(err, "unable to create the administration panel")
   113  	}
   114  
   115  	// Create the account panel
   116  	if pnl, err := accpanel.NewPanel(conf, log); err == nil {
   117  		siteacc.accountPanel = pnl
   118  	} else {
   119  		return errors.Wrap(err, "unable to create the account panel")
   120  	}
   121  
   122  	return nil
   123  }
   124  
   125  // RequestHandler returns the HTTP request handler of the service.
   126  func (siteacc *SiteAccounts) RequestHandler() http.Handler {
   127  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   128  		defer r.Body.Close()
   129  
   130  		// Get the active session for the request (or create a new one); a valid session object will always be returned
   131  		siteacc.sessions.PurgeSessions() // Remove expired sessions first
   132  		session, err := siteacc.sessions.HandleRequest(w, r)
   133  		if err != nil {
   134  			siteacc.log.Err(err).Msg("an error occurred while handling sessions")
   135  		}
   136  
   137  		epHandled := false
   138  		for _, ep := range getEndpoints() {
   139  			if ep.Path == r.URL.Path {
   140  				ep.Handler(siteacc, ep, w, r, session)
   141  				epHandled = true
   142  				break
   143  			}
   144  		}
   145  
   146  		if !epHandled {
   147  			w.WriteHeader(http.StatusBadRequest)
   148  			_, _ = w.Write([]byte(fmt.Sprintf("Unknown endpoint %v", r.URL.Path)))
   149  		}
   150  	})
   151  }
   152  
   153  // ShowAdministrationPanel writes the administration panel HTTP output directly to the response writer.
   154  func (siteacc *SiteAccounts) ShowAdministrationPanel(w http.ResponseWriter, r *http.Request, session *html.Session) error {
   155  	// The admin panel only shows the stored accounts and offers actions through links, so let it use cloned data
   156  	accounts := siteacc.accountsManager.CloneAccounts(true)
   157  	return siteacc.adminPanel.Execute(w, r, session, &accounts)
   158  }
   159  
   160  // ShowAccountPanel writes the account panel HTTP output directly to the response writer.
   161  func (siteacc *SiteAccounts) ShowAccountPanel(w http.ResponseWriter, r *http.Request, session *html.Session) error {
   162  	return siteacc.accountPanel.Execute(w, r, session)
   163  }
   164  
   165  // SitesManager returns the central sites manager instance.
   166  func (siteacc *SiteAccounts) SitesManager() *manager.SitesManager {
   167  	return siteacc.sitesManager
   168  }
   169  
   170  // AccountsManager returns the central accounts manager instance.
   171  func (siteacc *SiteAccounts) AccountsManager() *manager.AccountsManager {
   172  	return siteacc.accountsManager
   173  }
   174  
   175  // UsersManager returns the central users manager instance.
   176  func (siteacc *SiteAccounts) UsersManager() *manager.UsersManager {
   177  	return siteacc.usersManager
   178  }
   179  
   180  // AlertsDispatcher returns the central alerts dispatcher instance.
   181  func (siteacc *SiteAccounts) AlertsDispatcher() *alerting.Dispatcher {
   182  	return siteacc.alertsDispatcher
   183  }
   184  
   185  // GetPublicEndpoints returns a list of all public endpoints.
   186  func (siteacc *SiteAccounts) GetPublicEndpoints() []string {
   187  	// TODO: Only for local testing!
   188  	// return []string{"/"}
   189  
   190  	endpoints := make([]string, 0, 5)
   191  	for _, ep := range getEndpoints() {
   192  		if ep.IsPublic {
   193  			endpoints = append(endpoints, ep.Path)
   194  		}
   195  	}
   196  	return endpoints
   197  }
   198  
   199  func (siteacc *SiteAccounts) createStorage(driver string) (data.Storage, error) {
   200  	if driver == "file" {
   201  		return data.NewFileStorage(siteacc.conf, siteacc.log)
   202  	}
   203  
   204  	return nil, errors.Errorf("unknown storage driver %v", driver)
   205  }
   206  
   207  // New returns a new Site Accounts service instance.
   208  func New(conf *config.Configuration, log *zerolog.Logger) (*SiteAccounts, error) {
   209  	// Configure the accounts service
   210  	siteacc := new(SiteAccounts)
   211  	if err := siteacc.initialize(conf, log); err != nil {
   212  		return nil, fmt.Errorf("unable to initialize site accounts: %v", err)
   213  	}
   214  	return siteacc, nil
   215  }