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