From 123f931e76140dc7b967f2edea97d077c7ee6dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Fri, 25 Mar 2022 11:57:51 +0100 Subject: [PATCH 1/2] Various updates to the site accounts and Mentix services --- pkg/mentix/config/ids.go | 7 - pkg/mentix/connectors/gocdb.go | 10 +- pkg/mentix/exchangers/exchanger.go | 23 +-- .../exchangers/exporters/metrics/metrics.go | 4 +- pkg/mentix/exchangers/exporters/promsd.go | 2 - pkg/mentix/exchangers/exporters/webapi.go | 1 - pkg/mentix/meshdata/site.go | 47 ------ pkg/siteacc/account/contact/contact.go | 2 +- pkg/siteacc/account/edit/edit.go | 4 +- pkg/siteacc/account/edit/template.go | 2 +- pkg/siteacc/account/login/login.go | 4 +- pkg/siteacc/account/login/template.go | 2 +- pkg/siteacc/account/manage/manage.go | 4 +- pkg/siteacc/account/manage/template.go | 2 +- .../account/registration/registration.go | 4 +- pkg/siteacc/account/registration/template.go | 2 +- pkg/siteacc/account/settings/settings.go | 4 +- pkg/siteacc/account/settings/template.go | 2 +- pkg/siteacc/admin/panel.go | 4 +- pkg/siteacc/admin/template.go | 28 ---- pkg/siteacc/alerting/dispatcher.go | 20 ++- pkg/siteacc/config/endpoints.go | 15 -- pkg/siteacc/data/account.go | 16 +- pkg/siteacc/email/email.go | 12 +- pkg/siteacc/email/template.go | 35 +---- pkg/siteacc/endpoints.go | 137 +----------------- pkg/siteacc/html/template.go | 3 + pkg/siteacc/manager/accmanager.go | 99 ------------- 28 files changed, 59 insertions(+), 436 deletions(-) diff --git a/pkg/mentix/config/ids.go b/pkg/mentix/config/ids.go index 348b22b45e..176bf2e314 100644 --- a/pkg/mentix/config/ids.go +++ b/pkg/mentix/config/ids.go @@ -21,13 +21,6 @@ package config const ( // ConnectorIDGOCDB is the connector identifier for GOCDB. ConnectorIDGOCDB = "gocdb" - // ConnectorIDLocalFile is the connector identifier for local files. - ConnectorIDLocalFile = "localfile" -) - -const ( - // ImporterIDSiteRegistration is the identifier for the external site registration importer. - ImporterIDSiteRegistration = "sitereg" ) const ( diff --git a/pkg/mentix/connectors/gocdb.go b/pkg/mentix/connectors/gocdb.go index bfa28fe256..58b80850b3 100755 --- a/pkg/mentix/connectors/gocdb.go +++ b/pkg/mentix/connectors/gocdb.go @@ -135,16 +135,13 @@ func (connector *GOCDBConnector) querySites(meshData *meshdata.MeshData) error { for _, site := range sites.Sites { properties := connector.extensionsToMap(&site.Extensions) - siteID := meshdata.GetPropertyValue(properties, meshdata.PropertySiteID, "") - if len(siteID) == 0 { - return fmt.Errorf("site ID missing for site '%v'", site.ShortName) - } + // The site ID can be set through a property; by default, the site short name will be used + siteID := meshdata.GetPropertyValue(properties, meshdata.PropertySiteID, site.ShortName) // See if an organization has been defined using properties; otherwise, use the official name organization := meshdata.GetPropertyValue(properties, meshdata.PropertyOrganization, site.OfficialName) meshsite := &meshdata.Site{ - Type: meshdata.SiteTypeScienceMesh, // All sites stored in the GOCDB are part of the mesh ID: siteID, Name: site.ShortName, FullName: site.OfficialName, @@ -295,6 +292,9 @@ func (connector *GOCDBConnector) getServiceURL(service *gocdb.Service, endpoint svcURL.Path = endpoint.URL } else { svcURL.Path = path.Join(svcURL.Path, endpoint.URL) + if strings.HasSuffix(endpoint.URL, "/") { // Restore trailing slash if necessary + svcURL.Path += "/" + } } } } diff --git a/pkg/mentix/exchangers/exchanger.go b/pkg/mentix/exchangers/exchanger.go index 46ce511280..91def66822 100644 --- a/pkg/mentix/exchangers/exchanger.go +++ b/pkg/mentix/exchangers/exchanger.go @@ -55,8 +55,7 @@ type BaseExchanger struct { enabledConnectors []string - meshData *meshdata.MeshData - allowUnauthorizedSites bool + meshData *meshdata.MeshData locker sync.RWMutex } @@ -125,22 +124,11 @@ func (exchanger *BaseExchanger) storeMeshDataSet(meshDataSet meshdata.Map) error return nil } -func (exchanger *BaseExchanger) cloneMeshData(clean bool) *meshdata.MeshData { +func (exchanger *BaseExchanger) cloneMeshData() *meshdata.MeshData { exchanger.locker.RLock() meshDataClone := exchanger.meshData.Clone() exchanger.locker.RUnlock() - if clean && !exchanger.allowUnauthorizedSites { - cleanedSites := make([]*meshdata.Site, 0, len(meshDataClone.Sites)) - for _, site := range meshDataClone.Sites { - // Only keep authorized sites - if site.IsAuthorized { - cleanedSites = append(cleanedSites, site) - } - } - meshDataClone.Sites = cleanedSites - } - return meshDataClone } @@ -167,7 +155,7 @@ func (exchanger *BaseExchanger) SetEnabledConnectors(connectors []string) { // MeshData returns the stored mesh data. The returned data is cloned to prevent accidental data changes. // Unauthorized sites are also removed if this exchanger doesn't allow them. func (exchanger *BaseExchanger) MeshData() *meshdata.MeshData { - return exchanger.cloneMeshData(true) + return exchanger.cloneMeshData() } func (exchanger *BaseExchanger) setMeshData(meshData *meshdata.MeshData) { @@ -177,11 +165,6 @@ func (exchanger *BaseExchanger) setMeshData(meshData *meshdata.MeshData) { exchanger.meshData = meshData } -// SetAllowUnauthorizedSites sets whether this exchanger allows the exchange of unauthorized sites. -func (exchanger *BaseExchanger) SetAllowUnauthorizedSites(allow bool) { - exchanger.allowUnauthorizedSites = allow -} - // Locker returns the locking object. func (exchanger *BaseExchanger) Locker() *sync.RWMutex { return &exchanger.locker diff --git a/pkg/mentix/exchangers/exporters/metrics/metrics.go b/pkg/mentix/exchangers/exporters/metrics/metrics.go index 812435b7da..9863147d07 100644 --- a/pkg/mentix/exchangers/exporters/metrics/metrics.go +++ b/pkg/mentix/exchangers/exporters/metrics/metrics.go @@ -41,7 +41,6 @@ type Metrics struct { const ( keySiteID = "site_id" keySiteName = "site" - keySiteType = "site_type" keyServiceType = "service_type" ) @@ -70,7 +69,7 @@ func (m *Metrics) registerMetrics() error { Name: m.isScheduledStats.Name(), Description: m.isScheduledStats.Description(), Measure: m.isScheduledStats, - TagKeys: []tag.Key{tag.MustNewKey(keySiteID), tag.MustNewKey(keySiteName), tag.MustNewKey(keySiteType), tag.MustNewKey(keyServiceType)}, + TagKeys: []tag.Key{tag.MustNewKey(keySiteID), tag.MustNewKey(keySiteName), tag.MustNewKey(keyServiceType)}, Aggregation: view.LastValue(), } @@ -96,7 +95,6 @@ func (m *Metrics) exportSiteMetrics(site *meshdata.Site) error { mutators := make([]tag.Mutator, 0) mutators = append(mutators, tag.Insert(tag.MustNewKey(keySiteID), site.ID)) mutators = append(mutators, tag.Insert(tag.MustNewKey(keySiteName), site.Name)) - mutators = append(mutators, tag.Insert(tag.MustNewKey(keySiteType), meshdata.GetSiteTypeName(site.Type))) mutators = append(mutators, tag.Insert(tag.MustNewKey(keyServiceType), "SCIENCEMESH_HCHECK")) // Create a new context to serve the metrics diff --git a/pkg/mentix/exchangers/exporters/promsd.go b/pkg/mentix/exchangers/exporters/promsd.go index 4d51e9b641..2c33c75935 100755 --- a/pkg/mentix/exchangers/exporters/promsd.go +++ b/pkg/mentix/exchangers/exporters/promsd.go @@ -52,7 +52,6 @@ type PrometheusSDExporter struct { const ( labelSiteName = "__meta_mentix_site" - labelSiteType = "__meta_mentix_site_type" labelSiteID = "__meta_mentix_site_id" labelSiteCountry = "__meta_mentix_site_country" labelType = "__meta_mentix_type" @@ -77,7 +76,6 @@ func getScrapeTargetLabels(site *meshdata.Site, service *meshdata.Service, endpo endpointURL, _ := url.Parse(endpoint.URL) labels := map[string]string{ labelSiteName: site.Name, - labelSiteType: meshdata.GetSiteTypeName(site.Type), labelSiteID: site.ID, labelSiteCountry: site.CountryCode, labelType: endpoint.Type.Name, diff --git a/pkg/mentix/exchangers/exporters/webapi.go b/pkg/mentix/exchangers/exporters/webapi.go index e65b00c662..711166446d 100755 --- a/pkg/mentix/exchangers/exporters/webapi.go +++ b/pkg/mentix/exchangers/exporters/webapi.go @@ -39,7 +39,6 @@ func (exporter *WebAPIExporter) Activate(conf *config.Configuration, log *zerolo // Store WebAPI specifics exporter.SetEndpoint(conf.Exporters.WebAPI.Endpoint, conf.Exporters.WebAPI.IsProtected) exporter.SetEnabledConnectors(conf.Exporters.WebAPI.EnabledConnectors) - exporter.SetAllowUnauthorizedSites(true) exporter.RegisterActionHandler("", webapi.HandleDefaultQuery) diff --git a/pkg/mentix/meshdata/site.go b/pkg/mentix/meshdata/site.go index a6866a15d1..edf45d2ae8 100644 --- a/pkg/mentix/meshdata/site.go +++ b/pkg/mentix/meshdata/site.go @@ -23,26 +23,12 @@ import ( "net/url" "strings" - "github.com/cs3org/reva/pkg/mentix/accservice" "github.com/cs3org/reva/pkg/mentix/utils/network" ) -const ( - // SiteTypeScienceMesh flags a site as being part of the mesh. - SiteTypeScienceMesh SiteType = iota - // SiteTypeCommunity flags a site as being a community site. - SiteTypeCommunity -) - -// SiteType holds the type of a site. -type SiteType int - // Site represents a single site managed by Mentix. type Site struct { // Internal settings - Type SiteType `json:"-"` - IsAuthorized bool `json:"-"` - ID string Name string FullName string @@ -120,8 +106,6 @@ func (site *Site) Verify() error { // InferMissingData infers missing data from other data where possible. func (site *Site) InferMissingData() { // Infer missing data - site.IsAuthorized = site.getAuthorizationStatus() - if site.Homepage == "" { site.Homepage = fmt.Sprintf("http://www.%v", site.Domain) } else if site.Domain == "" { @@ -135,34 +119,3 @@ func (site *Site) InferMissingData() { service.InferMissingData() } } - -func (site *Site) getAuthorizationStatus() bool { - // ScienceMesh sites are always authorized - if site.Type == SiteTypeScienceMesh { - return true - } - - // Use the accounts service to find out whether the site is authorized - resp, err := accservice.Query("is-authorized", network.URLParams{"by": "siteid", "value": site.ID}) - if err == nil && resp.Success { - if authorized, ok := resp.Data.(bool); ok { - return authorized - } - } - - return false -} - -// GetSiteTypeName returns the readable name of the given site type. -func GetSiteTypeName(siteType SiteType) string { - switch siteType { - case SiteTypeScienceMesh: - return "sciencemesh" - - case SiteTypeCommunity: - return "community" - - default: - return "unknown" - } -} diff --git a/pkg/siteacc/account/contact/contact.go b/pkg/siteacc/account/contact/contact.go index 038db6a5a8..4312ee4af6 100644 --- a/pkg/siteacc/account/contact/contact.go +++ b/pkg/siteacc/account/contact/contact.go @@ -32,7 +32,7 @@ func (template *PanelTemplate) GetTitle() string { // GetCaption returns the caption which is displayed on the panel. func (template *PanelTemplate) GetCaption() string { - return "Contact the ScienceMesh administration" + return "Contact the ScienceMesh administration!" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/account/edit/edit.go b/pkg/siteacc/account/edit/edit.go index a4d40f257c..6a3852ce94 100644 --- a/pkg/siteacc/account/edit/edit.go +++ b/pkg/siteacc/account/edit/edit.go @@ -27,12 +27,12 @@ type PanelTemplate struct { // GetTitle returns the title of the panel. func (template *PanelTemplate) GetTitle() string { - return "ScienceMesh Account" + return "ScienceMesh Site Administrator Account" } // GetCaption returns the caption which is displayed on the panel. func (template *PanelTemplate) GetCaption() string { - return "Edit your ScienceMesh Account!" + return "Edit your ScienceMesh Site Administrator Account!" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/account/edit/template.go b/pkg/siteacc/account/edit/template.go index 0df4310aee..558f0295bd 100644 --- a/pkg/siteacc/account/edit/template.go +++ b/pkg/siteacc/account/edit/template.go @@ -99,7 +99,7 @@ html * { const tplBody = `
-

Edit your ScienceMesh account information below.

+

Edit your ScienceMesh Site Administrator Account information below.

Please note that you cannot modify your email address using this form.

 
diff --git a/pkg/siteacc/account/login/login.go b/pkg/siteacc/account/login/login.go index 078a128b32..d8b75ed98d 100644 --- a/pkg/siteacc/account/login/login.go +++ b/pkg/siteacc/account/login/login.go @@ -27,12 +27,12 @@ type PanelTemplate struct { // GetTitle returns the title of the panel. func (template *PanelTemplate) GetTitle() string { - return "ScienceMesh Account Login" + return "ScienceMesh Site Administrator Account Login" } // GetCaption returns the caption which is displayed on the panel. func (template *PanelTemplate) GetCaption() string { - return "Login to your ScienceMesh Account!" + return "Login to your ScienceMesh Site Administrator Account!" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/account/login/template.go b/pkg/siteacc/account/login/template.go index 501ff5609d..c47fe0edf2 100644 --- a/pkg/siteacc/account/login/template.go +++ b/pkg/siteacc/account/login/template.go @@ -109,7 +109,7 @@ html * { const tplBody = `
-

Login to your ScienceMesh account using the form below.

+

Login to your ScienceMesh Site Administrator Account using the form below.

 
diff --git a/pkg/siteacc/account/manage/manage.go b/pkg/siteacc/account/manage/manage.go index eff0ff5af3..928365b56a 100644 --- a/pkg/siteacc/account/manage/manage.go +++ b/pkg/siteacc/account/manage/manage.go @@ -27,12 +27,12 @@ type PanelTemplate struct { // GetTitle returns the title of the panel. func (template *PanelTemplate) GetTitle() string { - return "ScienceMesh Account" + return "ScienceMesh Site Administrator Account" } // GetCaption returns the caption which is displayed on the panel. func (template *PanelTemplate) GetCaption() string { - return "Welcome to your ScienceMesh Account!" + return "Welcome to your ScienceMesh Site Administrator Account!" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/account/manage/template.go b/pkg/siteacc/account/manage/template.go index 9862f02009..0d73b00c9d 100644 --- a/pkg/siteacc/account/manage/template.go +++ b/pkg/siteacc/account/manage/template.go @@ -63,7 +63,7 @@ html * { const tplBody = `

Hello {{.Account.FirstName}} {{.Account.LastName}},

-

On this page, you can manage your ScienceMesh user account. This includes editing your personal information, requesting access to the GOCDB and more.

+

On this page, you can manage your ScienceMesh Site Administrator Account. This includes editing your personal information, requesting access to the GOCDB and more.

 
diff --git a/pkg/siteacc/account/registration/registration.go b/pkg/siteacc/account/registration/registration.go index cbc96dab57..2128a05cf1 100644 --- a/pkg/siteacc/account/registration/registration.go +++ b/pkg/siteacc/account/registration/registration.go @@ -27,12 +27,12 @@ type PanelTemplate struct { // GetTitle returns the title of the panel. func (template *PanelTemplate) GetTitle() string { - return "ScienceMesh Account Registration" + return "ScienceMesh Site Administrator Account Registration" } // GetCaption returns the caption which is displayed on the panel. func (template *PanelTemplate) GetCaption() string { - return "Welcome to the ScienceMesh Account Registration!" + return "Welcome to the ScienceMesh Site Administrator Account Registration!" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/account/registration/template.go b/pkg/siteacc/account/registration/template.go index 97a4f0b2dd..babab0e52e 100644 --- a/pkg/siteacc/account/registration/template.go +++ b/pkg/siteacc/account/registration/template.go @@ -117,7 +117,7 @@ html * { const tplBody = `
-

Fill out the form below to register for a ScienceMesh account. A confirmation email will be sent to you shortly after registration.

+

Fill out the form below to register for a ScienceMesh Site Administrator account. A confirmation email will be sent to you shortly after registration.

 
diff --git a/pkg/siteacc/account/settings/settings.go b/pkg/siteacc/account/settings/settings.go index f6c17cde30..eaf0fc394f 100644 --- a/pkg/siteacc/account/settings/settings.go +++ b/pkg/siteacc/account/settings/settings.go @@ -27,12 +27,12 @@ type PanelTemplate struct { // GetTitle returns the title of the panel. func (template *PanelTemplate) GetTitle() string { - return "ScienceMesh Account" + return "ScienceMesh Site Administrator Account" } // GetCaption returns the caption which is displayed on the panel. func (template *PanelTemplate) GetCaption() string { - return "Configure your ScienceMesh Account!" + return "Configure your ScienceMesh Site Administrator Account!" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/account/settings/template.go b/pkg/siteacc/account/settings/template.go index 6c3a058f2a..182dc73c72 100644 --- a/pkg/siteacc/account/settings/template.go +++ b/pkg/siteacc/account/settings/template.go @@ -66,7 +66,7 @@ input[type="checkbox"] { const tplBody = `
-

Configure your ScienceMesh account below.

+

Configure your ScienceMesh Site Administrator Account below.

 
diff --git a/pkg/siteacc/admin/panel.go b/pkg/siteacc/admin/panel.go index 7d274d8b76..3e0e1d6c5d 100644 --- a/pkg/siteacc/admin/panel.go +++ b/pkg/siteacc/admin/panel.go @@ -63,12 +63,12 @@ func (panel *Panel) GetActiveTemplate(*html.Session, string) string { // GetTitle returns the title of the htmlPanel. func (panel *Panel) GetTitle() string { - return "ScienceMesh Administration Panel" + return "ScienceMesh Site Administrator Accounts Panel" } // GetCaption returns the caption which is displayed on the htmlPanel. func (panel *Panel) GetCaption() string { - return "Accounts ({{.Accounts | len}})" + return "ScienceMesh Site Administrator Accounts ({{.Accounts | len}})" } // GetContentJavaScript delivers additional JavaScript code. diff --git a/pkg/siteacc/admin/template.go b/pkg/siteacc/admin/template.go index 07374f7fdc..7dbfcb99c6 100644 --- a/pkg/siteacc/admin/template.go +++ b/pkg/siteacc/admin/template.go @@ -68,43 +68,15 @@ const tplBody = `

- GOCDB access: {{if .Data.GOCDBAccess}}Granted{{else}}Not granted{{end}}

- - {{if .Data.GOCDBAccess}} {{else}} {{end}} - - - - -  
diff --git a/pkg/siteacc/alerting/dispatcher.go b/pkg/siteacc/alerting/dispatcher.go index 760849887a..b09879abfd 100644 --- a/pkg/siteacc/alerting/dispatcher.go +++ b/pkg/siteacc/alerting/dispatcher.go @@ -74,6 +74,23 @@ func (dispatcher *Dispatcher) DispatchAlerts(alerts *template.Data, accounts dat } } } + + // Dispatch the alert to the global receiver (if set) + if dispatcher.conf.Email.NotificationsMail != "" { + globalAccount := data.Account{ // On-the-fly account representing the "global alerts receiver" + Email: dispatcher.conf.Email.NotificationsMail, + FirstName: "ScienceMesh", + LastName: "Global Alerts receiver", + Site: "Global", + Role: "Alerts receiver", + Settings: data.AccountSettings{ + ReceiveAlerts: true, + }, + } + if err := dispatcher.dispatchAlert(alert, &globalAccount); err != nil { + dispatcher.log.Err(err).Str("id", alert.Fingerprint).Str("recipient", globalAccount.Email).Msg("unable to dispatch alert to global alerts receiver") + } + } } return nil } @@ -86,6 +103,7 @@ func (dispatcher *Dispatcher) dispatchAlert(alert template.Alert, account *data. "Fingerprint": alert.Fingerprint, "Name": alert.Labels["alertname"], + "Service": alert.Labels["service_type"], "Instance": alert.Labels["instance"], "Job": alert.Labels["job"], "Severity": alert.Labels["severity"], @@ -96,7 +114,7 @@ func (dispatcher *Dispatcher) dispatchAlert(alert template.Alert, account *data. "Summary": alert.Annotations["summary"], } - return email.SendAlertNotification(account, []string{account.Email, dispatcher.conf.Email.NotificationsMail}, alertValues, *dispatcher.conf) + return email.SendAlertNotification(account, []string{account.Email}, alertValues, *dispatcher.conf) } // NewDispatcher creates a new dispatcher instance. diff --git a/pkg/siteacc/config/endpoints.go b/pkg/siteacc/config/endpoints.go index 9559f135d8..65252be146 100644 --- a/pkg/siteacc/config/endpoints.go +++ b/pkg/siteacc/config/endpoints.go @@ -24,13 +24,6 @@ const ( // EndpointAccount is the endpoint path of the web interface account panel. EndpointAccount = "/account" - // EndpointGenerateAPIKey is the endpoint path of the API key generator. - EndpointGenerateAPIKey = "/generate-api-key" - // EndpointVerifyAPIKey is the endpoint path for API key verification. - EndpointVerifyAPIKey = "/verify-api-key" - // EndpointAssignAPIKey is the endpoint path used for assigning an API key to an account. - EndpointAssignAPIKey = "/assign-api-key" - // EndpointList is the endpoint path for listing all stored accounts. EndpointList = "/list" // EndpointFind is the endpoint path for finding accounts. @@ -57,17 +50,9 @@ const ( // EndpointVerifyUserToken is the endpoint path for user token validation. EndpointVerifyUserToken = "/verify-user-token" - // EndpointAuthorize is the endpoint path for account authorization. - EndpointAuthorize = "/authorize" - // EndpointIsAuthorized is the endpoint path used to check the authorization status of an account. - EndpointIsAuthorized = "/is-authorized" - // EndpointGrantGOCDBAccess is the endpoint path for granting or revoking GOCDB access. EndpointGrantGOCDBAccess = "/grant-gocdb-access" - // EndpointUnregisterSite is the endpoint path for site unregistration. - EndpointUnregisterSite = "/unregister-site" - // EndpointDispatchAlert is the endpoint path for dispatching alerts from Prometheus. EndpointDispatchAlert = "/dispatch-alert" ) diff --git a/pkg/siteacc/data/account.go b/pkg/siteacc/data/account.go index 7d54beea5e..8b21814b6a 100644 --- a/pkg/siteacc/data/account.go +++ b/pkg/siteacc/data/account.go @@ -25,7 +25,6 @@ import ( "github.com/cs3org/reva/pkg/siteacc/password" "github.com/pkg/errors" - "github.com/cs3org/reva/pkg/mentix/key" "github.com/cs3org/reva/pkg/utils" ) @@ -50,9 +49,7 @@ type Account struct { // AccountData holds additional data for a site account. type AccountData struct { - APIKey key.APIKey `json:"apiKey"` - GOCDBAccess bool `json:"gocdbAccess"` - Authorized bool `json:"authorized"` + GOCDBAccess bool `json:"gocdbAccess"` } // AccountSettings holds additional settings for a site account. @@ -63,15 +60,6 @@ type AccountSettings struct { // Accounts holds an array of site accounts. type Accounts = []*Account -// GetSiteID returns the site ID (generated from the API key) for the given account. -func (acc *Account) GetSiteID() key.SiteIdentifier { - if id, err := key.CalculateSiteID(acc.Data.APIKey, key.SaltFromEmail(acc.Email)); err == nil { - return id - } - - return "" -} - // Update copies the data of the given account to this account. func (acc *Account) Update(other *Account, setPassword bool, copyData bool) error { if err := other.verify(false, false); err != nil { @@ -209,9 +197,7 @@ func NewAccount(email string, title, firstName, lastName string, site, role stri DateCreated: t, DateModified: t, Data: AccountData{ - APIKey: "", GOCDBAccess: false, - Authorized: false, }, Settings: AccountSettings{ ReceiveAlerts: true, diff --git a/pkg/siteacc/email/email.go b/pkg/siteacc/email/email.go index 9c73f47307..9de8d17747 100644 --- a/pkg/siteacc/email/email.go +++ b/pkg/siteacc/email/email.go @@ -52,17 +52,7 @@ func getEmailData(account *data.Account, conf config.Configuration, params map[s // SendAccountCreated sends an email about account creation. func SendAccountCreated(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { - return send(recipients, "ScienceMesh: Site account created", accountCreatedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) -} - -// SendAPIKeyAssigned sends an email about API key assignment. -func SendAPIKeyAssigned(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { - return send(recipients, "ScienceMesh: Your API key", apiKeyAssignedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) -} - -// SendAccountAuthorized sends an email about account authorization. -func SendAccountAuthorized(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { - return send(recipients, "ScienceMesh: Site registration authorized", accountAuthorizedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) + return send(recipients, "ScienceMesh: Site Administrator Account created", accountCreatedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) } // SendGOCDBAccessGranted sends an email about granted GOCDB access. diff --git a/pkg/siteacc/email/template.go b/pkg/siteacc/email/template.go index 3f3bf8e026..24efa65476 100644 --- a/pkg/siteacc/email/template.go +++ b/pkg/siteacc/email/template.go @@ -21,35 +21,12 @@ package email const accountCreatedTemplate = ` Dear {{.Account.FirstName}} {{.Account.LastName}}, -Your ScienceMesh account has been successfully created! +Your ScienceMesh Site Administrator Account has been successfully created! Log in to your account by visiting the user account panel: {{.AccountsAddress}} -Using this panel, you can modify your information, request an API key or access to the GOCDB, and more. - -Kind regards, -The ScienceMesh Team -` - -const apiKeyAssignedTemplate = ` -Dear {{.Account.FirstName}} {{.Account.LastName}}, - -An API key has been created for your account! - -To view your new API key, log in to your user account panel: -{{.AccountsAddress}} - -Your key will appear on the front page once logged in. - -Kind regards, -The ScienceMesh Team -` - -const accountAuthorizedTemplate = ` -Dear {{.Account.FirstName}} {{.Account.LastName}}, - -Congratulations - your site registration has been authorized! +Using this panel, you can modify your information, request access to the GOCDB, and more. Kind regards, The ScienceMesh Team @@ -61,7 +38,7 @@ Dear {{.Account.FirstName}} {{.Account.LastName}}, You have been granted access to the ScienceMesh GOCDB instance: {{.GOCDBAddress}} -Simply use your regular ScienceMesh account credentials to log in to the GOCDB. +Simply use your regular ScienceMesh Site Administrator Account credentials to log in to the GOCDB. Kind regards, The ScienceMesh Team @@ -89,9 +66,10 @@ const contactFormTemplate = ` ` const alertFiringNotificationTemplate = ` -Site {{.Params.Site}} has generated an alert: +Site '{{.Params.Site}}' has generated an alert: Type: {{.Params.Name}} + Service: {{.Params.Service}} Instance: {{.Params.Instance}} Job: {{.Params.Job}} Severity: {{.Params.Severity}} @@ -102,9 +80,10 @@ Site {{.Params.Site}} has generated an alert: ` const alertResolvedNotificationTemplate = ` -Site {{.Params.Site}} has resolved an alert: +Site '{{.Params.Site}}' has resolved an alert: Type: {{.Params.Name}} + Service: {{.Params.Service}} Instance: {{.Params.Instance}} Job: {{.Params.Job}} Severity: {{.Params.Severity}} diff --git a/pkg/siteacc/endpoints.go b/pkg/siteacc/endpoints.go index 50c4fd5419..9cbd72c0cf 100644 --- a/pkg/siteacc/endpoints.go +++ b/pkg/siteacc/endpoints.go @@ -26,18 +26,15 @@ import ( "net/url" "strings" - "github.com/cs3org/reva/pkg/mentix/key" "github.com/cs3org/reva/pkg/siteacc/config" "github.com/cs3org/reva/pkg/siteacc/data" "github.com/cs3org/reva/pkg/siteacc/html" - "github.com/cs3org/reva/pkg/siteacc/manager" "github.com/pkg/errors" "github.com/prometheus/alertmanager/template" ) const ( - invokerDefault = "" - invokerUser = "user" + invokerUser = "user" ) type methodCallback = func(*SiteAccounts, url.Values, []byte, *html.Session) (interface{}, error) @@ -68,10 +65,6 @@ func getEndpoints() []endpoint { // Form/panel endpoints {config.EndpointAdministration, callAdministrationEndpoint, nil, false}, {config.EndpointAccount, callAccountEndpoint, nil, true}, - // API key endpoints - {config.EndpointGenerateAPIKey, callMethodEndpoint, createMethodCallbacks(handleGenerateAPIKey, nil), false}, - {config.EndpointVerifyAPIKey, callMethodEndpoint, createMethodCallbacks(handleVerifyAPIKey, nil), false}, - {config.EndpointAssignAPIKey, callMethodEndpoint, createMethodCallbacks(nil, handleAssignAPIKey), false}, // General account endpoints {config.EndpointList, callMethodEndpoint, createMethodCallbacks(handleList, nil), false}, {config.EndpointFind, callMethodEndpoint, createMethodCallbacks(handleFind, nil), false}, @@ -86,15 +79,10 @@ func getEndpoints() []endpoint { {config.EndpointContact, callMethodEndpoint, createMethodCallbacks(nil, handleContact), true}, // Authentication endpoints {config.EndpointVerifyUserToken, callMethodEndpoint, createMethodCallbacks(handleVerifyUserToken, nil), true}, - // Authorization endpoints - {config.EndpointAuthorize, callMethodEndpoint, createMethodCallbacks(nil, handleAuthorize), false}, - {config.EndpointIsAuthorized, callMethodEndpoint, createMethodCallbacks(handleIsAuthorized, nil), false}, // Access management endpoints {config.EndpointGrantGOCDBAccess, callMethodEndpoint, createMethodCallbacks(nil, handleGrantGOCDBAccess), false}, // Alerting endpoints {config.EndpointDispatchAlert, callMethodEndpoint, createMethodCallbacks(nil, handleDispatchAlert), false}, - // Account site endpoints - {config.EndpointUnregisterSite, callMethodEndpoint, createMethodCallbacks(nil, handleUnregisterSite), false}, } return endpoints @@ -160,63 +148,6 @@ func callMethodEndpoint(siteacc *SiteAccounts, ep endpoint, w http.ResponseWrite _, _ = w.Write(jsonData) } -func handleGenerateAPIKey(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { - email := values.Get("email") - flags := key.FlagDefault - - if strings.EqualFold(values.Get("isScienceMesh"), "true") { - flags |= key.FlagScienceMesh - } - - if len(email) == 0 { - return nil, errors.Errorf("no email provided") - } - - apiKey, err := key.GenerateAPIKey(key.SaltFromEmail(email), flags) - if err != nil { - return nil, errors.Wrap(err, "unable to generate API key") - } - return map[string]string{"apiKey": apiKey}, nil -} - -func handleVerifyAPIKey(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { - apiKey := values.Get("apiKey") - email := values.Get("email") - - if len(apiKey) == 0 { - return nil, errors.Errorf("no API key provided") - } - - if len(email) == 0 { - return nil, errors.Errorf("no email provided") - } - - err := key.VerifyAPIKey(apiKey, key.SaltFromEmail(email)) - if err != nil { - return nil, errors.Wrap(err, "invalid API key") - } - return nil, nil -} - -func handleAssignAPIKey(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { - account, err := unmarshalRequestData(body) - if err != nil { - return nil, err - } - - flags := key.FlagDefault - if _, ok := values["isScienceMesh"]; ok { - flags |= key.FlagScienceMesh - } - - // Assign a new API key to the account through the accounts manager - if err := siteacc.AccountsManager().AssignAPIKeyToAccount(account, flags); err != nil { - return nil, errors.Wrap(err, "unable to assign API key") - } - - return nil, nil -} - func handleList(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { return siteacc.AccountsManager().CloneAccounts(true), nil } @@ -297,28 +228,6 @@ func handleRemove(siteacc *SiteAccounts, values url.Values, body []byte, session return nil, nil } -func handleIsAuthorized(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { - account, err := findAccount(siteacc, values.Get("by"), values.Get("value")) - if err != nil { - return nil, err - } - return account.Data.Authorized, nil -} - -func handleUnregisterSite(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { - account, err := unmarshalRequestData(body) - if err != nil { - return nil, err - } - - // Unregister the account's site through the accounts manager - if err := siteacc.AccountsManager().UnregisterAccountSite(account); err != nil { - return nil, errors.Wrap(err, "unable to unregister the site of the given account") - } - - return nil, nil -} - func handleLogin(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { account, err := unmarshalRequestData(body) if err != nil { @@ -393,36 +302,6 @@ func handleVerifyUserToken(siteacc *SiteAccounts, values url.Values, body []byte return newToken, nil } -func handleAuthorize(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { - account, err := unmarshalRequestData(body) - if err != nil { - return nil, err - } - - if val := values.Get("status"); len(val) > 0 { - var authorize bool - switch strings.ToLower(val) { - case "true": - authorize = true - - case "false": - authorize = false - - default: - return nil, errors.Errorf("unsupported authorization status %v", val[0]) - } - - // Authorize the account through the accounts manager - if err := siteacc.AccountsManager().AuthorizeAccount(account, authorize); err != nil { - return nil, errors.Wrap(err, "unable to (un)authorize account") - } - } else { - return nil, errors.Errorf("no authorization status provided") - } - - return nil, nil -} - func handleDispatchAlert(siteacc *SiteAccounts, values url.Values, body []byte, session *html.Session) (interface{}, error) { alertsData := &template.Data{} if err := json.Unmarshal(body, alertsData); err != nil { @@ -494,20 +373,6 @@ func processInvoker(siteacc *SiteAccounts, values url.Values, session *html.Sess var invokedByUser bool switch strings.ToLower(values.Get("invoker")) { - case invokerDefault: - // If the endpoint was called through the API, an API key must be provided identifying the account - apiKey := values.Get("apikey") - if apiKey == "" { - return "", false, errors.Errorf("no API key provided") - } - - accountFound, err := findAccount(siteacc, manager.FindByAPIKey, apiKey) - if err != nil { - return "", false, errors.Wrap(err, "no account for the specified API key found") - } - email = accountFound.Email - invokedByUser = false - case invokerUser: // If this endpoint was called by the user, set the account email from the stored session if session.LoggedInUser == nil { diff --git a/pkg/siteacc/html/template.go b/pkg/siteacc/html/template.go index b0fa54706d..420dcd6f35 100644 --- a/pkg/siteacc/html/template.go +++ b/pkg/siteacc/html/template.go @@ -106,6 +106,9 @@ const panelTemplate = ` label { font-weight: bold; } + h1 { + text-align: center; + } .box { width: 100%; diff --git a/pkg/siteacc/manager/accmanager.go b/pkg/siteacc/manager/accmanager.go index 4131c7972c..5d64840b24 100644 --- a/pkg/siteacc/manager/accmanager.go +++ b/pkg/siteacc/manager/accmanager.go @@ -19,17 +19,14 @@ package manager import ( - "path" "strings" "sync" "time" - "github.com/cs3org/reva/pkg/mentix/key" "github.com/cs3org/reva/pkg/siteacc/config" "github.com/cs3org/reva/pkg/siteacc/data" "github.com/cs3org/reva/pkg/siteacc/email" "github.com/cs3org/reva/pkg/siteacc/manager/gocdb" - "github.com/cs3org/reva/pkg/siteacc/sitereg" "github.com/cs3org/reva/pkg/smtpclient" "github.com/pkg/errors" "github.com/rs/zerolog" @@ -39,10 +36,6 @@ import ( const ( // FindByEmail holds the string value of the corresponding search criterium. FindByEmail = "email" - // FindByAPIKey holds the string value of the corresponding search criterium. - FindByAPIKey = "apikey" - // FindBySiteID holds the string value of the corresponding search criterium. - FindBySiteID = "siteid" ) // AccountsManager is responsible for all site account related tasks. @@ -129,12 +122,6 @@ func (mngr *AccountsManager) findAccount(by string, value string) (*data.Account case FindByEmail: account = mngr.findAccountByPredicate(func(account *data.Account) bool { return strings.EqualFold(account.Email, value) }) - case FindByAPIKey: - account = mngr.findAccountByPredicate(func(account *data.Account) bool { return account.Data.APIKey == value }) - - case FindBySiteID: - account = mngr.findAccountByPredicate(func(account *data.Account) bool { return account.GetSiteID() == value }) - default: return nil, errors.Errorf("invalid search type %v", by) } @@ -266,31 +253,6 @@ func (mngr *AccountsManager) FindAccountEx(by string, value string, cloneAccount return account, nil } -// AuthorizeAccount sets the authorization status of the account identified by the account email; if no such account exists, an error is returned. -func (mngr *AccountsManager) AuthorizeAccount(accountData *data.Account, authorized bool) error { - mngr.mutex.Lock() - defer mngr.mutex.Unlock() - - account, err := mngr.findAccount(FindByEmail, accountData.Email) - if err != nil { - return errors.Wrap(err, "no account with the specified email exists") - } - - authorizedOld := account.Data.Authorized - account.Data.Authorized = authorized - - mngr.storage.AccountUpdated(account) - mngr.writeAllAccounts() - - if account.Data.Authorized && account.Data.Authorized != authorizedOld { - mngr.sendEmail(account, nil, email.SendAccountAuthorized) - } - - mngr.callListeners(account, AccountsListener.AccountUpdated) - - return nil -} - // GrantGOCDBAccess sets the GOCDB access status of the account identified by the account email; if no such account exists, an error is returned. func (mngr *AccountsManager) GrantGOCDBAccess(accountData *data.Account, grantAccess bool) error { mngr.mutex.Lock() @@ -316,67 +278,6 @@ func (mngr *AccountsManager) GrantGOCDBAccess(accountData *data.Account, grantAc return nil } -// AssignAPIKeyToAccount is used to assign a new API key to the account identified by the account email; if no such account exists, an error is returned. -func (mngr *AccountsManager) AssignAPIKeyToAccount(accountData *data.Account, flags int) error { - mngr.mutex.Lock() - defer mngr.mutex.Unlock() - - account, err := mngr.findAccount(FindByEmail, accountData.Email) - if err != nil { - return errors.Wrap(err, "no account with the specified email exists") - } - - if len(account.Data.APIKey) > 0 { - return errors.Errorf("the account already has an API key assigned") - } - - for { - apiKey, err := key.GenerateAPIKey(key.SaltFromEmail(account.Email), flags) - if err != nil { - return errors.Wrap(err, "error while generating API key") - } - - // See if the key already exists (super extremely unlikely); if so, generate a new one and try again - if acc, _ := mngr.findAccount(FindByAPIKey, apiKey); acc != nil { - continue - } - - account.Data.APIKey = apiKey - break - } - - mngr.storage.AccountUpdated(account) - mngr.writeAllAccounts() - - mngr.sendEmail(account, nil, email.SendAPIKeyAssigned) - mngr.callListeners(account, AccountsListener.AccountUpdated) - - return nil -} - -// UnregisterAccountSite unregisters the site associated with the given account. -func (mngr *AccountsManager) UnregisterAccountSite(accountData *data.Account) error { - mngr.mutex.RLock() - defer mngr.mutex.RUnlock() - - account, err := mngr.findAccount(FindByEmail, accountData.Email) - if err != nil { - return errors.Wrap(err, "no account with the specified email exists") - } - - salt := key.SaltFromEmail(account.Email) - siteID, err := key.CalculateSiteID(account.Data.APIKey, salt) - if err != nil { - return errors.Wrap(err, "unable to get site ID") - } - - if err := sitereg.UnregisterSite(path.Join(mngr.conf.Mentix.URL, mngr.conf.Mentix.SiteRegistrationEndpoint), account.Data.APIKey, siteID, salt); err != nil { - return errors.Wrap(err, "error while unregistering the site") - } - - return nil -} - // RemoveAccount removes the account identified by the account email; if no such account exists, an error is returned. func (mngr *AccountsManager) RemoveAccount(accountData *data.Account) error { mngr.mutex.Lock() From bdce269b5302d4926d00f2ecb1f6adc7dd886575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Fri, 25 Mar 2022 12:00:51 +0100 Subject: [PATCH 2/2] Add changelog --- changelog/unreleased/siteacc-upd-2.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 changelog/unreleased/siteacc-upd-2.md diff --git a/changelog/unreleased/siteacc-upd-2.md b/changelog/unreleased/siteacc-upd-2.md new file mode 100644 index 0000000000..b270b1a045 --- /dev/null +++ b/changelog/unreleased/siteacc-upd-2.md @@ -0,0 +1,9 @@ +Enhancement: Further Site Accounts improvements + +Yet another PR to update the site accounts (and Mentix): +New default site ID; +Include service type in alerts; +Naming unified; +Remove obsolete stuff. + +https://github.com/cs3org/reva/pull/2672