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