James Moger
2014-09-25 54cc7d7c2483d7ca100a5db47f4e1e98bd97c7fe
commit | author | age
23e08c 1 /*
JM 2  * Copyright 2013 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.manager;
17
18 import java.io.BufferedReader;
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.InputStreamReader;
24 import java.lang.reflect.Type;
25 import java.text.MessageFormat;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Date;
29 import java.util.List;
a8100b 30 import java.util.Locale;
23e08c 31 import java.util.Map;
JM 32 import java.util.TimeZone;
33
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36
66a5e2 37 import org.eclipse.jgit.api.CloneCommand;
JM 38 import org.eclipse.jgit.api.FetchCommand;
39 import org.eclipse.jgit.api.Git;
40 import org.eclipse.jgit.lib.Ref;
23e08c 41 import org.eclipse.jgit.lib.Repository;
66a5e2 42 import org.eclipse.jgit.transport.RefSpec;
23e08c 43 import org.slf4j.Logger;
JM 44 import org.slf4j.LoggerFactory;
45
b2fec2 46 import ro.fortsoft.pf4j.PluginState;
84f406 47 import ro.fortsoft.pf4j.PluginWrapper;
027267 48 import ro.fortsoft.pf4j.Version;
84f406 49
23e08c 50 import com.gitblit.Constants;
JM 51 import com.gitblit.Constants.AccessPermission;
52 import com.gitblit.Constants.AccessRestrictionType;
53 import com.gitblit.Constants.FederationRequest;
54 import com.gitblit.Constants.FederationToken;
55 import com.gitblit.GitBlitException;
56 import com.gitblit.IStoredSettings;
57 import com.gitblit.Keys;
58 import com.gitblit.models.FederationModel;
59 import com.gitblit.models.FederationProposal;
60 import com.gitblit.models.FederationSet;
61 import com.gitblit.models.ForkModel;
62 import com.gitblit.models.GitClientApplication;
d7c5a6 63 import com.gitblit.models.Mailing;
23e08c 64 import com.gitblit.models.Metric;
b2fec2 65 import com.gitblit.models.PluginRegistry.InstallState;
e5d0ba 66 import com.gitblit.models.PluginRegistry.PluginRegistration;
JM 67 import com.gitblit.models.PluginRegistry.PluginRelease;
23e08c 68 import com.gitblit.models.ProjectModel;
JM 69 import com.gitblit.models.RegistrantAccessPermission;
70 import com.gitblit.models.RepositoryModel;
71 import com.gitblit.models.RepositoryUrl;
72 import com.gitblit.models.SearchResult;
73 import com.gitblit.models.ServerSettings;
74 import com.gitblit.models.ServerStatus;
75 import com.gitblit.models.SettingModel;
76 import com.gitblit.models.TeamModel;
77 import com.gitblit.models.UserModel;
5e3521 78 import com.gitblit.tickets.ITicketService;
245836 79 import com.gitblit.transport.ssh.IPublicKeyManager;
bcc8a0 80 import com.gitblit.transport.ssh.SshKey;
23e08c 81 import com.gitblit.utils.ArrayUtils;
JM 82 import com.gitblit.utils.HttpUtils;
83 import com.gitblit.utils.JsonUtils;
84 import com.gitblit.utils.ObjectCache;
85 import com.gitblit.utils.StringUtils;
e58e09 86 import com.gitblit.utils.XssFilter;
23e08c 87 import com.google.gson.Gson;
JM 88 import com.google.gson.JsonIOException;
89 import com.google.gson.JsonSyntaxException;
90 import com.google.gson.reflect.TypeToken;
91
92 /**
93  * GitblitManager is an aggregate interface delegate.  It implements all the manager
94  * interfaces and delegates most methods calls to the proper manager implementation.
95  * It's primary purpose is to provide complete management control to the git
96  * upload and receive pack functions.
97  *
98  * GitblitManager also implements several integration methods when it is required
99  * to manipulate several manages for one operation.
100  *
101  * @author James Moger
102  *
103  */
104 public class GitblitManager implements IGitblit {
105
106     protected final Logger logger = LoggerFactory.getLogger(getClass());
107
108     protected final ObjectCache<Collection<GitClientApplication>> clientApplications = new ObjectCache<Collection<GitClientApplication>>();
109
110     protected final IStoredSettings settings;
111
112     protected final IRuntimeManager runtimeManager;
113
41a7e4 114     protected final IPluginManager pluginManager;
JM 115
23e08c 116     protected final INotificationManager notificationManager;
JM 117
118     protected final IUserManager userManager;
119
120     protected final IAuthenticationManager authenticationManager;
121
245836 122     protected final IPublicKeyManager publicKeyManager;
JM 123
23e08c 124     protected final IRepositoryManager repositoryManager;
JM 125
126     protected final IProjectManager projectManager;
127
128     protected final IFederationManager federationManager;
129
130     public GitblitManager(
131             IRuntimeManager runtimeManager,
41a7e4 132             IPluginManager pluginManager,
23e08c 133             INotificationManager notificationManager,
JM 134             IUserManager userManager,
135             IAuthenticationManager authenticationManager,
245836 136             IPublicKeyManager publicKeyManager,
23e08c 137             IRepositoryManager repositoryManager,
JM 138             IProjectManager projectManager,
41a7e4 139             IFederationManager federationManager) {
23e08c 140
JM 141         this.settings = runtimeManager.getSettings();
142         this.runtimeManager = runtimeManager;
41a7e4 143         this.pluginManager = pluginManager;
23e08c 144         this.notificationManager = notificationManager;
JM 145         this.userManager = userManager;
146         this.authenticationManager = authenticationManager;
245836 147         this.publicKeyManager = publicKeyManager;
23e08c 148         this.repositoryManager = repositoryManager;
JM 149         this.projectManager = projectManager;
150         this.federationManager = federationManager;
151     }
152
153     @Override
154     public GitblitManager start() {
155         loadSettingModels(runtimeManager.getSettingsModel());
156         return this;
157     }
158
159     @Override
160     public GitblitManager stop() {
161         return this;
162     }
163
164     /*
165      * IGITBLIT
166      */
167
168     /**
169      * Creates a personal fork of the specified repository. The clone is view
170      * restricted by default and the owner of the source repository is given
171      * access to the clone.
172      *
173      * @param repository
174      * @param user
175      * @return the repository model of the fork, if successful
176      * @throws GitBlitException
177      */
178     @Override
179     public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
180         String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name)));
181         String fromUrl = MessageFormat.format("file://{0}/{1}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name);
182
183         // clone the repository
184         try {
66a5e2 185             Repository canonical = getRepository(repository.name);
JM 186             File folder = new File(repositoryManager.getRepositoriesFolder(), cloneName);
187             CloneCommand clone = new CloneCommand();
188             clone.setBare(true);
189
190             // fetch branches with exclusions
191             Collection<Ref> branches = canonical.getRefDatabase().getRefs(Constants.R_HEADS).values();
192             List<String> branchesToClone = new ArrayList<String>();
193             for (Ref branch : branches) {
194                 String name = branch.getName();
195                 if (name.startsWith(Constants.R_TICKET)) {
196                     // exclude ticket branches
197                     continue;
198                 }
199                 branchesToClone.add(name);
200             }
201             clone.setBranchesToClone(branchesToClone);
202             clone.setURI(fromUrl);
203             clone.setDirectory(folder);
204             Git git = clone.call();
205
206             // fetch tags
207             FetchCommand fetch  = git.fetch();
208             fetch.setRefSpecs(new RefSpec("+refs/tags/*:refs/tags/*"));
209             fetch.call();
210
211             git.getRepository().close();
23e08c 212         } catch (Exception e) {
JM 213             throw new GitBlitException(e);
214         }
215
216         // create a Gitblit repository model for the clone
217         RepositoryModel cloneModel = repository.cloneAs(cloneName);
218         // owner has REWIND/RW+ permissions
219         cloneModel.addOwner(user.username);
a08e6f 220
JM 221         // ensure initial access restriction of the fork
222         // is not lower than the source repository  (issue-495/ticket-167)
223         if (repository.accessRestriction.exceeds(cloneModel.accessRestriction)) {
224             cloneModel.accessRestriction = repository.accessRestriction;
225         }
226
23e08c 227         repositoryManager.updateRepositoryModel(cloneName, cloneModel, false);
JM 228
229         // add the owner of the source repository to the clone's access list
230         if (!ArrayUtils.isEmpty(repository.owners)) {
231             for (String owner : repository.owners) {
232                 UserModel originOwner = userManager.getUserModel(owner);
ba2f9a 233                 if (originOwner != null && !originOwner.canClone(cloneModel)) {
JM 234                     // origin owner can't yet clone fork, grant explicit clone access
23e08c 235                     originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
JM 236                     reviseUser(originOwner.username, originOwner);
237                 }
238             }
239         }
240
241         // grant origin's user list clone permission to fork
242         List<String> users = repositoryManager.getRepositoryUsers(repository);
243         List<UserModel> cloneUsers = new ArrayList<UserModel>();
244         for (String name : users) {
245             if (!name.equalsIgnoreCase(user.username)) {
246                 UserModel cloneUser = userManager.getUserModel(name);
ba2f9a 247                 if (cloneUser.canClone(repository) && !cloneUser.canClone(cloneModel)) {
JM 248                     // origin user can't yet clone fork, grant explicit clone access
23e08c 249                     cloneUser.setRepositoryPermission(cloneName, AccessPermission.CLONE);
JM 250                 }
251                 cloneUsers.add(cloneUser);
252             }
253         }
254         userManager.updateUserModels(cloneUsers);
255
256         // grant origin's team list clone permission to fork
257         List<String> teams = repositoryManager.getRepositoryTeams(repository);
258         List<TeamModel> cloneTeams = new ArrayList<TeamModel>();
259         for (String name : teams) {
260             TeamModel cloneTeam = userManager.getTeamModel(name);
ba2f9a 261             if (cloneTeam.canClone(repository) && !cloneTeam.canClone(cloneModel)) {
JM 262                 // origin team can't yet clone fork, grant explicit clone access
23e08c 263                 cloneTeam.setRepositoryPermission(cloneName, AccessPermission.CLONE);
JM 264             }
265             cloneTeams.add(cloneTeam);
266         }
267         userManager.updateTeamModels(cloneTeams);
268
269         // add this clone to the cached model
270         repositoryManager.addToCachedRepositoryList(cloneModel);
271         return cloneModel;
272     }
273
274     /**
275      * Adds a TeamModel object.
276      *
277      * @param team
278      */
279     @Override
280     public void addTeam(TeamModel team) throws GitBlitException {
281         if (!userManager.updateTeamModel(team)) {
282             throw new GitBlitException("Failed to add team!");
283         }
284     }
285
286     /**
287      * Updates the TeamModel object for the specified name.
288      *
289      * @param teamname
290      * @param team
291      */
292     @Override
293     public void reviseTeam(String teamname, TeamModel team) throws GitBlitException {
294         if (!teamname.equalsIgnoreCase(team.name)) {
295             if (userManager.getTeamModel(team.name) != null) {
296                 throw new GitBlitException(MessageFormat.format(
297                         "Failed to rename ''{0}'' because ''{1}'' already exists.", teamname,
298                         team.name));
299             }
300         }
301         if (!userManager.updateTeamModel(teamname, team)) {
302             throw new GitBlitException("Failed to update team!");
303         }
304     }
305
306     /**
307      * Adds a user object.
308      *
309      * @param user
310      * @throws GitBlitException
311      */
312     @Override
313     public void addUser(UserModel user) throws GitBlitException {
314         if (!userManager.updateUserModel(user)) {
315             throw new GitBlitException("Failed to add user!");
316         }
317     }
318
319     /**
320      * Updates a user object keyed by username. This method allows
321      * for renaming a user.
322      *
323      * @param username
324      * @param user
325      * @throws GitBlitException
326      */
327     @Override
328     public void reviseUser(String username, UserModel user) throws GitBlitException {
329         if (!username.equalsIgnoreCase(user.username)) {
330             if (userManager.getUserModel(user.username) != null) {
331                 throw new GitBlitException(MessageFormat.format(
332                         "Failed to rename ''{0}'' because ''{1}'' already exists.", username,
333                         user.username));
334             }
335
336             // rename repositories and owner fields for all repositories
337             for (RepositoryModel model : repositoryManager.getRepositoryModels(user)) {
338                 if (model.isUsersPersonalRepository(username)) {
339                     // personal repository
340                     model.addOwner(user.username);
341                     String oldRepositoryName = model.name;
342                     model.name = user.getPersonalPath() + model.name.substring(model.projectPath.length());
343                     model.projectPath = user.getPersonalPath();
344                     repositoryManager.updateRepositoryModel(oldRepositoryName, model, false);
345                 } else if (model.isOwner(username)) {
346                     // common/shared repo
347                     model.addOwner(user.username);
348                     repositoryManager.updateRepositoryModel(model.name, model, false);
349                 }
350             }
f5ca16 351
JM 352             // rename the user's ssh public keystore
353             getPublicKeyManager().renameUser(username, user.username);
23e08c 354         }
JM 355         if (!userManager.updateUserModel(username, user)) {
356             throw new GitBlitException("Failed to update user!");
357         }
358     }
359
360     /**
361      * Returns a list of repository URLs and the user access permission.
362      *
363      * @param request
364      * @param user
365      * @param repository
366      * @return a list of repository urls
367      */
368     @Override
369     public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
370         if (user == null) {
371             user = UserModel.ANONYMOUS;
372         }
373         String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
374
375         List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
376         // http/https url
377         if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
378             AccessPermission permission = user.getRepositoryPermission(repository).permission;
379             if (permission.exceeds(AccessPermission.NONE)) {
380                 list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
381             }
382         }
383
384         // add all other urls
385         // {0} = repository
386         // {1} = username
387         for (String url : settings.getStrings(Keys.web.otherUrls)) {
388             if (url.contains("{1}")) {
389                 // external url requires username, only add url IF we have one
390                 if (!StringUtils.isEmpty(username)) {
391                     list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
392                 }
393             } else {
394                 // external url does not require username
395                 list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
396             }
397         }
398         return list;
399     }
400
401     protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) {
14cbbe 402         String gitblitUrl = settings.getString(Keys.web.canonicalUrl, null);
JM 403         if (StringUtils.isEmpty(gitblitUrl)) {
404             gitblitUrl = HttpUtils.getGitblitURL(request);
405         }
23e08c 406         StringBuilder sb = new StringBuilder();
14cbbe 407         sb.append(gitblitUrl);
23e08c 408         sb.append(Constants.R_PATH);
JM 409         sb.append(repository.name);
410
411         // inject username into repository url if authentication is required
412         if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE)
413                 && !StringUtils.isEmpty(username)) {
414             sb.insert(sb.indexOf("://") + 3, username + "@");
415         }
416         return sb.toString();
417     }
418
419
420     /**
421      * Returns the list of custom client applications to be used for the
422      * repository url panel;
423      *
424      * @return a collection of client applications
425      */
426     @Override
427     public Collection<GitClientApplication> getClientApplications() {
428         // prefer user definitions, if they exist
429         File userDefs = new File(runtimeManager.getBaseFolder(), "clientapps.json");
430         if (userDefs.exists()) {
431             Date lastModified = new Date(userDefs.lastModified());
432             if (clientApplications.hasCurrent("user", lastModified)) {
433                 return clientApplications.getObject("user");
434             } else {
435                 // (re)load user definitions
436                 try {
437                     InputStream is = new FileInputStream(userDefs);
438                     Collection<GitClientApplication> clients = readClientApplications(is);
439                     is.close();
440                     if (clients != null) {
441                         clientApplications.updateObject("user", lastModified, clients);
442                         return clients;
443                     }
444                 } catch (IOException e) {
445                     logger.error("Failed to deserialize " + userDefs.getAbsolutePath(), e);
446                 }
447             }
448         }
449
450         // no user definitions, use system definitions
451         if (!clientApplications.hasCurrent("system", new Date(0))) {
452             try {
1d78b8 453                 InputStream is = GitblitManager.class.getResourceAsStream("/clientapps.json");
23e08c 454                 Collection<GitClientApplication> clients = readClientApplications(is);
JM 455                 is.close();
456                 if (clients != null) {
457                     clientApplications.updateObject("system", new Date(0), clients);
458                 }
459             } catch (IOException e) {
460                 logger.error("Failed to deserialize clientapps.json resource!", e);
461             }
462         }
463
464         return clientApplications.getObject("system");
465     }
466
467     private Collection<GitClientApplication> readClientApplications(InputStream is) {
468         try {
469             Type type = new TypeToken<Collection<GitClientApplication>>() {
470             }.getType();
471             InputStreamReader reader = new InputStreamReader(is);
472             Gson gson = JsonUtils.gson();
473             Collection<GitClientApplication> links = gson.fromJson(reader, type);
474             return links;
475         } catch (JsonIOException e) {
476             logger.error("Error deserializing client applications!", e);
477         } catch (JsonSyntaxException e) {
478             logger.error("Error deserializing client applications!", e);
479         }
480         return null;
481     }
482
483     /**
484      * Parse the properties file and aggregate all the comments by the setting
485      * key. A setting model tracks the current value, the default value, the
486      * description of the setting and and directives about the setting.
487      *
488      * @return Map<String, SettingModel>
489      */
490     private void loadSettingModels(ServerSettings settingsModel) {
491         try {
492             // Read bundled Gitblit properties to extract setting descriptions.
493             // This copy is pristine and only used for populating the setting
494             // models map.
1d78b8 495             InputStream is = GitblitManager.class.getResourceAsStream("/reference.properties");
23e08c 496             BufferedReader propertiesReader = new BufferedReader(new InputStreamReader(is));
JM 497             StringBuilder description = new StringBuilder();
498             SettingModel setting = new SettingModel();
499             String line = null;
500             while ((line = propertiesReader.readLine()) != null) {
501                 if (line.length() == 0) {
502                     description.setLength(0);
503                     setting = new SettingModel();
504                 } else {
505                     if (line.charAt(0) == '#') {
506                         if (line.length() > 1) {
507                             String text = line.substring(1).trim();
508                             if (SettingModel.CASE_SENSITIVE.equals(text)) {
509                                 setting.caseSensitive = true;
510                             } else if (SettingModel.RESTART_REQUIRED.equals(text)) {
511                                 setting.restartRequired = true;
512                             } else if (SettingModel.SPACE_DELIMITED.equals(text)) {
513                                 setting.spaceDelimited = true;
514                             } else if (text.startsWith(SettingModel.SINCE)) {
515                                 try {
516                                     setting.since = text.split(" ")[1];
517                                 } catch (Exception e) {
518                                     setting.since = text;
519                                 }
520                             } else {
521                                 description.append(text);
522                                 description.append('\n');
523                             }
524                         }
525                     } else {
526                         String[] kvp = line.split("=", 2);
527                         String key = kvp[0].trim();
528                         setting.name = key;
529                         setting.defaultValue = kvp[1].trim();
530                         setting.currentValue = setting.defaultValue;
531                         setting.description = description.toString().trim();
532                         settingsModel.add(setting);
533                         description.setLength(0);
534                         setting = new SettingModel();
535                     }
536                 }
537             }
538             propertiesReader.close();
539         } catch (NullPointerException e) {
540             logger.error("Failed to find resource copy of gitblit.properties");
541         } catch (IOException e) {
542             logger.error("Failed to load resource copy of gitblit.properties");
543         }
544     }
545
5e3521 546     /**
JM 547      * Throws an exception if trying to get a ticket service.
548      *
549      */
550     @Override
551     public ITicketService getTicketService() {
552         throw new RuntimeException("This class does not have a ticket service!");
553     }
554
245836 555     @Override
JM 556     public IPublicKeyManager getPublicKeyManager() {
557         return publicKeyManager;
558     }
559
23e08c 560     /*
JM 561      * ISTOREDSETTINGS
562      *
563      * these methods are necessary for (nearly) seamless Groovy hook operation
564      * after the massive refactor.
565      */
566
567     public boolean getBoolean(String key, boolean defaultValue) {
568         return runtimeManager.getSettings().getBoolean(key, defaultValue);
569     }
570
571     public String getString(String key, String defaultValue) {
572         return runtimeManager.getSettings().getString(key, defaultValue);
573     }
574
575     public int getInteger(String key, int defaultValue) {
576         return runtimeManager.getSettings().getInteger(key, defaultValue);
577     }
578
579     public List<String> getStrings(String key) {
580         return runtimeManager.getSettings().getStrings(key);
581     }
582
583     /*
584      * RUNTIME MANAGER
585      */
586
587     @Override
588     public File getBaseFolder() {
589         return runtimeManager.getBaseFolder();
590     }
591
592     @Override
593     public void setBaseFolder(File folder) {
594         runtimeManager.setBaseFolder(folder);
595     }
596
597     @Override
598     public Date getBootDate() {
599         return runtimeManager.getBootDate();
600     }
601
602     @Override
603     public ServerSettings getSettingsModel() {
604         return runtimeManager.getSettingsModel();
605     }
606
607     @Override
608     public boolean isServingRepositories() {
609         return runtimeManager.isServingRepositories();
610     }
611
612     @Override
05f229 613     public boolean isServingHTTP() {
JM 614         return runtimeManager.isServingHTTP();
615     }
616
617     @Override
618     public boolean isServingGIT() {
619         return runtimeManager.isServingGIT();
620     }
621
622     @Override
623     public boolean isServingSSH() {
624         return runtimeManager.isServingSSH();
625     }
626
627     @Override
23e08c 628     public TimeZone getTimezone() {
JM 629         return runtimeManager.getTimezone();
630     }
631
632     @Override
a8100b 633     public Locale getLocale() {
JM 634         return runtimeManager.getLocale();
635     }
636
637     @Override
23e08c 638     public boolean isDebugMode() {
JM 639         return runtimeManager.isDebugMode();
640     }
641
642     @Override
643     public File getFileOrFolder(String key, String defaultFileOrFolder) {
644         return runtimeManager.getFileOrFolder(key, defaultFileOrFolder);
645     }
646
647     @Override
648     public File getFileOrFolder(String fileOrFolder) {
649         return runtimeManager.getFileOrFolder(fileOrFolder);
650     }
651
652     @Override
653     public IStoredSettings getSettings() {
654         return runtimeManager.getSettings();
655     }
656
657     @Override
658     public boolean updateSettings(Map<String, String> updatedSettings) {
659         return runtimeManager.updateSettings(updatedSettings);
660     }
661
662     @Override
663     public ServerStatus getStatus() {
664         return runtimeManager.getStatus();
665     }
666
fc3a39 667     @Override
JM 668     public XssFilter getXssFilter() {
669         return runtimeManager.getXssFilter();
670     }
671
23e08c 672     /*
JM 673      * NOTIFICATION MANAGER
674      */
675
676     @Override
74221e 677     public boolean isSendingMail() {
JM 678         return notificationManager.isSendingMail();
679     }
680
681     @Override
23e08c 682     public void sendMailToAdministrators(String subject, String message) {
JM 683         notificationManager.sendMailToAdministrators(subject, message);
684     }
685
686     @Override
687     public void sendMail(String subject, String message, Collection<String> toAddresses) {
688         notificationManager.sendMail(subject, message, toAddresses);
689     }
690
691     @Override
692     public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
693         notificationManager.sendHtmlMail(subject, message, toAddresses);
694     }
695
696     @Override
d7c5a6 697     public void send(Mailing mail) {
JM 698         notificationManager.send(mail);
afaab5 699     }
JM 700
23e08c 701     /*
JM 702      * SESSION MANAGER
703      */
704
705     @Override
706     public UserModel authenticate(String username, char[] password) {
707         return authenticationManager.authenticate(username, password);
708     }
709
710     @Override
711     public UserModel authenticate(HttpServletRequest httpRequest) {
712         UserModel user = authenticationManager.authenticate(httpRequest, false);
713         if (user == null) {
714             user = federationManager.authenticate(httpRequest);
715         }
716         return user;
717     }
44e2ee 718
e3b636 719     @Override
bcc8a0 720     public UserModel authenticate(String username, SshKey key) {
44e2ee 721         return authenticationManager.authenticate(username, key);
e3b636 722     }
44e2ee 723
23e08c 724     @Override
JM 725     public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) {
726         UserModel user = authenticationManager.authenticate(httpRequest, requiresCertificate);
727         if (user == null) {
728             user = federationManager.authenticate(httpRequest);
729         }
730         return user;
731     }
732
733     @Override
7ab32b 734     public String getCookie(HttpServletRequest request) {
JM 735         return authenticationManager.getCookie(request);
736     }
737
738     @Override
ec7ed8 739     @Deprecated
23e08c 740     public void setCookie(HttpServletResponse response, UserModel user) {
JM 741         authenticationManager.setCookie(response, user);
742     }
743
744     @Override
ec7ed8 745     public void setCookie(HttpServletRequest request, HttpServletResponse response, UserModel user) {
JM 746         authenticationManager.setCookie(request, response, user);
747     }
748
749     @Override
750     @Deprecated
23e08c 751     public void logout(HttpServletResponse response, UserModel user) {
JM 752         authenticationManager.logout(response, user);
753     }
754
755     @Override
ec7ed8 756     public void logout(HttpServletRequest request, HttpServletResponse response, UserModel user) {
JM 757         authenticationManager.logout(request, response, user);
758     }
759
760     @Override
23e08c 761     public boolean supportsCredentialChanges(UserModel user) {
JM 762         return authenticationManager.supportsCredentialChanges(user);
763     }
764
765     @Override
766     public boolean supportsDisplayNameChanges(UserModel user) {
767         return authenticationManager.supportsDisplayNameChanges(user);
768     }
769
770     @Override
771     public boolean supportsEmailAddressChanges(UserModel user) {
772         return authenticationManager.supportsEmailAddressChanges(user);
773     }
774
775     @Override
776     public boolean supportsTeamMembershipChanges(UserModel user) {
777         return authenticationManager.supportsTeamMembershipChanges(user);
778     }
779
780     @Override
781     public boolean supportsTeamMembershipChanges(TeamModel team) {
782         return authenticationManager.supportsTeamMembershipChanges(team);
783     }
784
785     /*
786      * USER MANAGER
787      */
788
789     @Override
790     public void setup(IRuntimeManager runtimeManager) {
791     }
792
793     @Override
794     public boolean isInternalAccount(String username) {
795         return userManager.isInternalAccount(username);
796     }
797
798     @Override
799     public List<String> getAllUsernames() {
800         return userManager.getAllUsernames();
801     }
802
803     @Override
804     public List<UserModel> getAllUsers() {
805         return userManager.getAllUsers();
806     }
807
808     @Override
809     public boolean deleteUser(String username) {
810         return userManager.deleteUser(username);
811     }
812
813     @Override
814     public UserModel getUserModel(String username) {
815         return userManager.getUserModel(username);
816     }
817
818     @Override
819     public List<TeamModel> getAllTeams() {
820         return userManager.getAllTeams();
821     }
822
823     @Override
824     public TeamModel getTeamModel(String teamname) {
825         return userManager.getTeamModel(teamname);
826     }
827
828     @Override
829     public String getCookie(UserModel model) {
830         return userManager.getCookie(model);
831     }
832
833     @Override
834     public UserModel getUserModel(char[] cookie) {
835         return userManager.getUserModel(cookie);
836     }
837
838     @Override
839     public boolean updateUserModel(UserModel model) {
840         return userManager.updateUserModel(model);
841     }
842
843     @Override
844     public boolean updateUserModels(Collection<UserModel> models) {
845         return userManager.updateUserModels(models);
846     }
847
848     @Override
849     public boolean updateUserModel(String username, UserModel model) {
850         return userManager.updateUserModel(username, model);
851     }
852
853     @Override
854     public boolean deleteUserModel(UserModel model) {
855         return userManager.deleteUserModel(model);
856     }
857
858     @Override
859     public List<String> getAllTeamNames() {
860         return userManager.getAllTeamNames();
861     }
862
863     @Override
864     public List<String> getTeamNamesForRepositoryRole(String role) {
865         return userManager.getTeamNamesForRepositoryRole(role);
866     }
867
868     @Override
869     public boolean updateTeamModel(TeamModel model) {
870         return userManager.updateTeamModel(model);
871     }
872
873     @Override
874     public boolean updateTeamModels(Collection<TeamModel> models) {
875         return userManager.updateTeamModels(models);
876     }
877
878     @Override
879     public boolean updateTeamModel(String teamname, TeamModel model) {
880         return userManager.updateTeamModel(teamname, model);
881     }
882
883     @Override
884     public boolean deleteTeamModel(TeamModel model) {
885         return userManager.deleteTeamModel(model);
886     }
887
888     @Override
889     public List<String> getUsernamesForRepositoryRole(String role) {
890         return userManager.getUsernamesForRepositoryRole(role);
891     }
892
893     @Override
894     public boolean renameRepositoryRole(String oldRole, String newRole) {
895         return userManager.renameRepositoryRole(oldRole, newRole);
896     }
897
898     @Override
899     public boolean deleteRepositoryRole(String role) {
900         return userManager.deleteRepositoryRole(role);
901     }
902
903     @Override
904     public boolean deleteTeam(String teamname) {
905         return userManager.deleteTeam(teamname);
906     }
907
908     /*
909      * REPOSITORY MANAGER
910      */
911
912     @Override
913     public Date getLastActivityDate() {
914         return repositoryManager.getLastActivityDate();
915     }
916
917     @Override
918     public File getRepositoriesFolder() {
919         return repositoryManager.getRepositoriesFolder();
920     }
921
922     @Override
923     public File getHooksFolder() {
924         return repositoryManager.getHooksFolder();
925     }
926
927     @Override
928     public File getGrapesFolder() {
929         return repositoryManager.getGrapesFolder();
930     }
931
932     @Override
933     public List<RegistrantAccessPermission> getUserAccessPermissions(UserModel user) {
934         return repositoryManager.getUserAccessPermissions(user);
935     }
936
937     @Override
938     public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) {
939         return repositoryManager.getUserAccessPermissions(repository);
940     }
941
942     @Override
943     public boolean setUserAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
944         return repositoryManager.setUserAccessPermissions(repository, permissions);
945     }
946
947     @Override
948     public List<String> getRepositoryUsers(RepositoryModel repository) {
949         return repositoryManager.getRepositoryUsers(repository);
950     }
951
952     @Override
953     public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {
954         return repositoryManager.getTeamAccessPermissions(repository);
955     }
956
957     @Override
958     public boolean setTeamAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
959         return repositoryManager.setTeamAccessPermissions(repository, permissions);
960     }
961
962     @Override
963     public List<String> getRepositoryTeams(RepositoryModel repository) {
964         return repositoryManager.getRepositoryTeams(repository);
965     }
966     @Override
967     public void addToCachedRepositoryList(RepositoryModel model) {
968         repositoryManager.addToCachedRepositoryList(model);
969     }
970
971     @Override
972     public void resetRepositoryListCache() {
973         repositoryManager.resetRepositoryListCache();
974     }
975
976     @Override
ce07c4 977     public void resetRepositoryCache(String repositoryName) {
JM 978         repositoryManager.resetRepositoryCache(repositoryName);
979     }
980
981     @Override
23e08c 982     public List<String> getRepositoryList() {
JM 983         return repositoryManager.getRepositoryList();
984     }
985
986     @Override
987     public Repository getRepository(String repositoryName) {
988         return repositoryManager.getRepository(repositoryName);
989     }
990
991     @Override
992     public Repository getRepository(String repositoryName, boolean logError) {
993         return repositoryManager.getRepository(repositoryName, logError);
994     }
995
996     @Override
e58e09 997     public List<RepositoryModel> getRepositoryModels() {
JM 998         return repositoryManager.getRepositoryModels();
999     }
1000
1001     @Override
23e08c 1002     public List<RepositoryModel> getRepositoryModels(UserModel user) {
JM 1003         return repositoryManager.getRepositoryModels(user);
1004     }
1005
1006     @Override
1007     public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) {
1008         return repositoryManager.getRepositoryModel(repositoryName);
1009     }
1010
1011     @Override
1012     public RepositoryModel getRepositoryModel(String repositoryName) {
1013         return repositoryManager.getRepositoryModel(repositoryName);
1014     }
1015
1016     @Override
1017     public long getStarCount(RepositoryModel repository) {
1018         return repositoryManager.getStarCount(repository);
1019     }
1020
1021     @Override
1022     public boolean hasRepository(String repositoryName) {
1023         return repositoryManager.hasRepository(repositoryName);
1024     }
1025
1026     @Override
1027     public boolean hasRepository(String repositoryName, boolean caseSensitiveCheck) {
1028         return repositoryManager.hasRepository(repositoryName, caseSensitiveCheck);
1029     }
1030
1031     @Override
1032     public boolean hasFork(String username, String origin) {
1033         return repositoryManager.hasFork(username, origin);
1034     }
1035
1036     @Override
1037     public String getFork(String username, String origin) {
1038         return repositoryManager.getFork(username, origin);
1039     }
1040
1041     @Override
1042     public ForkModel getForkNetwork(String repository) {
1043         return repositoryManager.getForkNetwork(repository);
1044     }
1045
1046     @Override
1047     public long updateLastChangeFields(Repository r, RepositoryModel model) {
1048         return repositoryManager.updateLastChangeFields(r, model);
1049     }
1050
1051     @Override
1052     public List<Metric> getRepositoryDefaultMetrics(RepositoryModel model, Repository repository) {
1053         return repositoryManager.getRepositoryDefaultMetrics(model, repository);
1054     }
1055
1056     @Override
1057     public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
1058             boolean isCreate) throws GitBlitException {
1059         repositoryManager.updateRepositoryModel(repositoryName, repository, isCreate);
1060     }
1061
1062     @Override
1063     public void updateConfiguration(Repository r, RepositoryModel repository) {
1064         repositoryManager.updateConfiguration(r, repository);
1065     }
1066
1067     @Override
b4ed66 1068     public boolean canDelete(RepositoryModel model) {
JM 1069         return repositoryManager.canDelete(model);
1070     }
1071
1072     @Override
23e08c 1073     public boolean deleteRepositoryModel(RepositoryModel model) {
JM 1074         return repositoryManager.deleteRepositoryModel(model);
1075     }
1076
1077     @Override
1078     public boolean deleteRepository(String repositoryName) {
1079         return repositoryManager.deleteRepository(repositoryName);
1080     }
1081
1082     @Override
1083     public List<String> getAllScripts() {
1084         return repositoryManager.getAllScripts();
1085     }
1086
1087     @Override
1088     public List<String> getPreReceiveScriptsInherited(RepositoryModel repository) {
1089         return repositoryManager.getPreReceiveScriptsInherited(repository);
1090     }
1091
1092     @Override
1093     public List<String> getPreReceiveScriptsUnused(RepositoryModel repository) {
1094         return repositoryManager.getPreReceiveScriptsUnused(repository);
1095     }
1096
1097     @Override
1098     public List<String> getPostReceiveScriptsInherited(RepositoryModel repository) {
1099         return repositoryManager.getPostReceiveScriptsInherited(repository);
1100     }
1101
1102     @Override
1103     public List<String> getPostReceiveScriptsUnused(RepositoryModel repository) {
1104         return repositoryManager.getPostReceiveScriptsUnused(repository);
1105     }
1106
1107     @Override
1108     public List<SearchResult> search(String query, int page, int pageSize, List<String> repositories) {
1109         return repositoryManager.search(query, page, pageSize, repositories);
1110     }
1111
1112     @Override
1113     public boolean isCollectingGarbage() {
1114         return repositoryManager.isCollectingGarbage();
1115     }
1116
1117     @Override
1118     public boolean isCollectingGarbage(String repositoryName) {
1119         return repositoryManager.isCollectingGarbage(repositoryName);
1120     }
1121
1122     /*
1123      * PROJECT MANAGER
1124      */
1125
1126     @Override
1127     public List<ProjectModel> getProjectModels(UserModel user, boolean includeUsers) {
1128         return projectManager.getProjectModels(user, includeUsers);
1129     }
1130
1131     @Override
1132     public ProjectModel getProjectModel(String name, UserModel user) {
1133         return projectManager.getProjectModel(name, user);
1134     }
1135
1136     @Override
1137     public ProjectModel getProjectModel(String name) {
1138         return projectManager.getProjectModel(name);
1139     }
1140
1141     @Override
1142     public List<ProjectModel> getProjectModels(List<RepositoryModel> repositoryModels, boolean includeUsers) {
1143         return projectManager.getProjectModels(repositoryModels, includeUsers);
1144     }
1145
1146     /*
1147      * FEDERATION MANAGER
1148      */
1149
1150     @Override
1151     public File getProposalsFolder() {
1152         return federationManager.getProposalsFolder();
1153     }
1154
1155     @Override
1156     public boolean canFederate() {
1157         return federationManager.canFederate();
1158     }
1159
1160     @Override
1161     public UserModel getFederationUser() {
1162         return federationManager.getFederationUser();
1163     }
1164
1165     @Override
1166     public List<FederationModel> getFederationRegistrations() {
1167         return federationManager.getFederationRegistrations();
1168     }
1169
1170     @Override
1171     public FederationModel getFederationRegistration(String url, String name) {
1172         return federationManager.getFederationRegistration(url, name);
1173     }
1174
1175     @Override
1176     public List<FederationSet> getFederationSets(String gitblitUrl) {
1177         return federationManager.getFederationSets(gitblitUrl);
1178     }
1179
1180     @Override
1181     public List<String> getFederationTokens() {
1182         return federationManager.getFederationTokens();
1183     }
1184
1185     @Override
1186     public String getFederationToken(FederationToken type) {
1187         return federationManager.getFederationToken(type);
1188     }
1189
1190     @Override
1191     public String getFederationToken(String value) {
1192         return federationManager.getFederationToken(value);
1193     }
1194
1195     @Override
1196     public boolean validateFederationRequest(FederationRequest req, String token) {
1197         return federationManager.validateFederationRequest(req, token);
1198     }
1199
1200     @Override
1201     public boolean acknowledgeFederationStatus(String identification, FederationModel registration) {
1202         return federationManager.acknowledgeFederationStatus(identification, registration);
1203     }
1204
1205     @Override
1206     public List<FederationModel> getFederationResultRegistrations() {
1207         return federationManager.getFederationResultRegistrations();
1208     }
1209
1210     @Override
1211     public boolean submitFederationProposal(FederationProposal proposal, String gitblitUrl) {
1212         return federationManager.submitFederationProposal(proposal, gitblitUrl);
1213     }
1214
1215     @Override
1216     public List<FederationProposal> getPendingFederationProposals() {
1217         return federationManager.getPendingFederationProposals();
1218     }
1219
1220     @Override
1221     public Map<String, RepositoryModel> getRepositories(String gitblitUrl, String token) {
1222         return federationManager.getRepositories(gitblitUrl, token);
1223     }
1224
1225     @Override
1226     public FederationProposal createFederationProposal(String gitblitUrl, String token) {
1227         return federationManager.createFederationProposal(gitblitUrl, token);
1228     }
1229
1230     @Override
1231     public FederationProposal getPendingFederationProposal(String token) {
1232         return federationManager.getPendingFederationProposal(token);
1233     }
1234
1235     @Override
1236     public boolean deletePendingFederationProposal(FederationProposal proposal) {
1237         return federationManager.deletePendingFederationProposal(proposal);
1238     }
388a23 1239
JM 1240     @Override
1241     public void closeAll() {
1242         repositoryManager.closeAll();
1243     }
1244
1245     @Override
1246     public void close(String repository) {
1247         repositoryManager.close(repository);
1248     }
1249
1250     @Override
1251     public boolean isIdle(Repository repository) {
1252         return repositoryManager.isIdle(repository);
1253     }
84f406 1254
e5d0ba 1255     /*
JM 1256      * PLUGIN MANAGER
1257      */
1258
84f406 1259     @Override
027267 1260     public Version getSystemVersion() {
JM 1261         return pluginManager.getSystemVersion();
1262     }
1263
1264     @Override
413e9b 1265     public void startPlugins() {
JM 1266         pluginManager.startPlugins();
1267     }
1268
1269     @Override
1270     public void stopPlugins() {
1271         pluginManager.stopPlugins();
1272     }
1273
1274     @Override
b2fec2 1275     public List<PluginWrapper> getPlugins() {
JM 1276         return pluginManager.getPlugins();
413e9b 1277     }
JM 1278
1279     @Override
b2fec2 1280     public PluginWrapper getPlugin(String pluginId) {
JM 1281         return pluginManager.getPlugin(pluginId);
1282     }
1283
1284     @Override
1285     public List<Class<?>> getExtensionClasses(String pluginId) {
1286         return pluginManager.getExtensionClasses(pluginId);
1287     }
1288
1289     @Override
1290     public <T> List<T> getExtensions(Class<T> clazz) {
1291         return pluginManager.getExtensions(clazz);
1292     }
1293
1294     @Override
1295     public PluginWrapper whichPlugin(Class<?> clazz) {
1296         return pluginManager.whichPlugin(clazz);
1297     }
1298
1299     @Override
1300     public PluginState startPlugin(String pluginId) {
1301         return pluginManager.startPlugin(pluginId);
1302     }
1303
1304     @Override
1305     public PluginState stopPlugin(String pluginId) {
1306         return pluginManager.stopPlugin(pluginId);
1307     }
1308
1309     @Override
1310     public boolean disablePlugin(String pluginId) {
1311         return pluginManager.disablePlugin(pluginId);
1312     }
1313
1314     @Override
1315     public boolean enablePlugin(String pluginId) {
1316         return pluginManager.enablePlugin(pluginId);
1317     }
1318
1319     @Override
cf4004 1320     public boolean uninstallPlugin(String pluginId) {
JM 1321         return pluginManager.uninstallPlugin(pluginId);
b2fec2 1322     }
JM 1323
1324     @Override
e90206 1325     public boolean refreshRegistry(boolean verifyChecksum) {
JM 1326         return pluginManager.refreshRegistry(verifyChecksum);
b2fec2 1327     }
JM 1328
1329     @Override
1330     public boolean installPlugin(String url, boolean verifyChecksum) throws IOException {
1331         return pluginManager.installPlugin(url, verifyChecksum);
1332     }
1333
1334     @Override
74f3d9 1335     public boolean upgradePlugin(String pluginId, String url, boolean verifyChecksum) throws IOException {
JM 1336         return pluginManager.upgradePlugin(pluginId, url, verifyChecksum);
1337     }
1338
1339     @Override
b2fec2 1340     public List<PluginRegistration> getRegisteredPlugins() {
JM 1341         return pluginManager.getRegisteredPlugins();
1342     }
1343
1344     @Override
1345     public List<PluginRegistration> getRegisteredPlugins(InstallState state) {
1346         return pluginManager.getRegisteredPlugins(state);
1347     }
1348
1349     @Override
fad6b4 1350     public PluginRegistration lookupPlugin(String pluginId) {
JM 1351         return pluginManager.lookupPlugin(pluginId);
b2fec2 1352     }
JM 1353
1354     @Override
fad6b4 1355     public PluginRelease lookupRelease(String pluginId, String version) {
JM 1356         return pluginManager.lookupRelease(pluginId, version);
413e9b 1357     }
23e08c 1358 }