protected IUserService createUserService(File realmFile) { IUserService service = null; if (realmFile.getName().toLowerCase().endsWith(".conf")) { // config-based realm file service = new ConfigUserService(realmFile); } assert service != null; if (!realmFile.exists()) { // Create the Administrator account for a new realm file try { realmFile.createNewFile(); } catch (IOException x) { logger.error(MessageFormat.format("COULD NOT CREATE REALM FILE {0}!", realmFile), x); } UserModel admin = new UserModel("admin"); admin.password = "******"; admin.canAdmin = true; admin.excludeFromFederation = true; service.updateUserModel(admin); } return service; }
public EditRepositoryPage() { // create constructor super(); isCreate = true; RepositoryModel model = new RepositoryModel(); String restriction = GitBlit.getString(Keys.git.defaultAccessRestriction, null); model.accessRestriction = AccessRestrictionType.fromName(restriction); String authorization = GitBlit.getString(Keys.git.defaultAuthorizationControl, null); model.authorizationControl = AuthorizationControl.fromName(authorization); GitBlitWebSession session = GitBlitWebSession.get(); UserModel user = session.getUser(); if (user != null && user.canCreate() && !user.canAdmin()) { // personal create permissions, inject personal repository path model.name = user.getPersonalPath() + "/"; model.projectPath = user.getPersonalPath(); model.addOwner(user.username); // personal repositories are private by default model.accessRestriction = AccessRestrictionType.VIEW; model.authorizationControl = AuthorizationControl.NAMED; } setupPage(model); setStatelessHint(false); setOutputMarkupId(true); }
/** * Retrieve the user object for the specified username. * * @param username * @return a user object or null */ @Override public UserModel getUserModel(String username) { Properties allUsers = read(); String userInfo = allUsers.getProperty(username.toLowerCase()); if (userInfo == null) { return null; } UserModel model = new UserModel(username.toLowerCase()); String[] userValues = userInfo.split(","); model.password = userValues[0]; for (int i = 1; i < userValues.length; i++) { String role = userValues[i]; switch (role.charAt(0)) { case '#': // Permissions if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) { model.canAdmin = true; } else if (role.equalsIgnoreCase(Constants.NOT_FEDERATED_ROLE)) { model.excludeFromFederation = true; } break; default: model.addRepository(role); } } // set the teams for the user for (TeamModel team : teams.values()) { if (team.hasUser(username)) { model.teams.add(DeepCopier.copy(team)); } } return model; }
@Override public boolean updateUserModel(String username, UserModel model) { if (model.isLocalAccount() || supportsCredentialChanges()) { if (!model.isLocalAccount() && !supportsTeamMembershipChanges()) { // teams are externally controlled - copy from original model UserModel existingModel = getUserModel(username); model = DeepCopier.copy(model); model.teams.clear(); model.teams.addAll(existingModel.teams); } return serviceImpl.updateUserModel(username, model); } if (model.username.equals(username)) { // passwords are not persisted by the backing user service model.password = null; if (!model.isLocalAccount() && !supportsTeamMembershipChanges()) { // teams are externally controlled- copy from original model UserModel existingModel = getUserModel(username); model = DeepCopier.copy(model); model.teams.clear(); model.teams.addAll(existingModel.teams); } return serviceImpl.updateUserModel(username, model); } logger.error("Users can not be renamed!"); return false; }
@Test public void testUnauthorizedLoginClone() throws Exception { // restrict repository access RepositoryModel model = GitBlit.self().getRepositoryModel("ticgit.git"); model.accessRestriction = AccessRestrictionType.CLONE; model.authorizationControl = AuthorizationControl.NAMED; UserModel user = new UserModel("james"); user.password = "******"; GitBlit.self().updateUserModel(user.username, user, true); GitBlit.self().updateRepositoryModel(model.name, model, false); FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE); // delete any existing working folder boolean cloned = false; try { CloneCommand clone = Git.cloneRepository(); clone.setURI(MessageFormat.format("{0}/git/ticgit.git", url)); clone.setDirectory(ticgit2Folder); clone.setBare(false); clone.setCloneAllBranches(true); clone.setCredentialsProvider( new UsernamePasswordCredentialsProvider(user.username, user.password)); close(clone.call()); cloned = true; } catch (Exception e) { // swallow the exception which we expect } assertFalse("Unauthorized login cloned a repository?!", cloned); FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE); // switch to authenticated model.authorizationControl = AuthorizationControl.AUTHENTICATED; GitBlit.self().updateRepositoryModel(model.name, model, false); // try clone again cloned = false; CloneCommand clone = Git.cloneRepository(); clone.setURI(MessageFormat.format("{0}/git/ticgit.git", url)); clone.setDirectory(ticgit2Folder); clone.setBare(false); clone.setCloneAllBranches(true); clone.setCredentialsProvider( new UsernamePasswordCredentialsProvider(user.username, user.password)); close(clone.call()); cloned = true; assertTrue("Authenticated login could not clone!", cloned); FileUtils.delete(ticgit2Folder, FileUtils.RECURSIVE); // restore anonymous repository access model.accessRestriction = AccessRestrictionType.NONE; model.authorizationControl = AuthorizationControl.NAMED; GitBlit.self().updateRepositoryModel(model.name, model, false); GitBlit.self().deleteUser(user.username); }
protected void setAccountType(UserModel user) { if (user != null) { if (!StringUtils.isEmpty(user.password) && !Constants.EXTERNAL_ACCOUNT.equalsIgnoreCase(user.password) && !"StoredInLDAP".equalsIgnoreCase(user.password)) { user.accountType = AccountType.LOCAL; } else { user.accountType = getAccountType(); } } }
/** * Updates/writes and replaces a complete user object keyed by username. This method allows for * renaming a user. * * @param username the old username * @param model the user object to use for username * @return true if update is successful */ @Override public boolean updateUserModel(String username, UserModel model) { try { Properties allUsers = read(); UserModel oldUser = getUserModel(username); ArrayList<String> roles = new ArrayList<String>(model.repositories); // Permissions if (model.canAdmin) { roles.add(Constants.ADMIN_ROLE); } if (model.excludeFromFederation) { roles.add(Constants.NOT_FEDERATED_ROLE); } StringBuilder sb = new StringBuilder(); sb.append(model.password); sb.append(','); for (String role : roles) { sb.append(role); sb.append(','); } // trim trailing comma sb.setLength(sb.length() - 1); allUsers.remove(username.toLowerCase()); allUsers.put(model.username.toLowerCase(), sb.toString()); // null check on "final" teams because JSON-sourced UserModel // can have a null teams object if (model.teams != null) { // update team cache for (TeamModel team : model.teams) { TeamModel t = getTeamModel(team.name); if (t == null) { // new team t = team; } t.removeUser(username); t.addUser(model.username); updateTeamCache(allUsers, t.name, t); } // check for implicit team removal if (oldUser != null) { for (TeamModel team : oldUser.teams) { if (!model.isTeamMember(team.name)) { team.removeUser(username); updateTeamCache(allUsers, team.name, team); } } } } write(allUsers); return true; } catch (Throwable t) { logger.error(MessageFormat.format("Failed to update user model {0}!", model.username), t); } return false; }
/** * Unfortunately must repeat part of AuthorizaitonStrategy here because that mechanism does not * take PageParameters into consideration, only page instantiation. * * <p>Repository Owners should be able to edit their repository. */ private void checkPermissions(RepositoryModel model) { boolean authenticateAdmin = GitBlit.getBoolean(Keys.web.authenticateAdminPages, true); boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, true); GitBlitWebSession session = GitBlitWebSession.get(); UserModel user = session.getUser(); if (allowAdmin) { if (authenticateAdmin) { if (user == null) { // No Login Available error(getString("gb.errorAdminLoginRequired"), true); } if (isCreate) { // Create Repository if (!user.canCreate() && !user.canAdmin()) { // Only administrators or permitted users may create error(getString("gb.errorOnlyAdminMayCreateRepository"), true); } } else { // Edit Repository if (user.canAdmin()) { // Admins can edit everything isAdmin = true; return; } else { if (!model.isOwner(user.username)) { // User is not an Admin nor Owner error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true); } } } } } else { // No Administration Permitted error(getString("gb.errorAdministrationDisabled"), true); } }
private boolean sendEmail(UserModel user, X509Metadata metadata, File zip) { // send email try { if (mail.isReady()) { Message message = mail.createMessage(user.emailAddress); message.setSubject("Your Gitblit client certificate for " + metadata.serverHostname); // body of email String body = X509Utils.processTemplate( new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"), metadata); if (StringUtils.isEmpty(body)) { body = MessageFormat.format( "Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName()); } Multipart mp = new MimeMultipart(); MimeBodyPart messagePart = new MimeBodyPart(); messagePart.setText(body); mp.addBodyPart(messagePart); // attach zip MimeBodyPart filePart = new MimeBodyPart(); FileDataSource fds = new FileDataSource(zip); filePart.setDataHandler(new DataHandler(fds)); filePart.setFileName(fds.getName()); mp.addBodyPart(filePart); message.setContent(mp); mail.sendNow(message); return true; } else { JOptionPane.showMessageDialog( GitblitAuthority.this, "Sorry, the mail server settings are not configured properly.\nCan not send email.", Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE); } } catch (Exception e) { Utils.showException(GitblitAuthority.this, e); } return false; }
/** * Determine if the user can access the repository and perform the specified action. * * @param repository * @param user * @param action * @return true if user may execute the action on the repository */ @Override protected boolean canAccess(RepositoryModel repository, UserModel user, String action) { if (!GitBlit.getBoolean(Keys.git.enableGitServlet, true)) { // Git Servlet disabled return false; } boolean readOnly = repository.isFrozen; if (readOnly || repository.accessRestriction.atLeast(AccessRestrictionType.PUSH)) { boolean authorizedUser = user.canAccessRepository(repository); if (action.equals(gitReceivePack)) { // Push request if (!readOnly && authorizedUser) { // clone-restricted or push-authorized return true; } else { // user is unauthorized to push to this repository logger.warn( MessageFormat.format( "user {0} is not authorized to push to {1}", user.username, repository)); return false; } } else if (action.equals(gitUploadPack)) { // Clone request boolean cloneRestricted = repository.accessRestriction.atLeast(AccessRestrictionType.CLONE); if (!cloneRestricted || (cloneRestricted && authorizedUser)) { // push-restricted or clone-authorized return true; } else { // user is unauthorized to clone this repository logger.warn( MessageFormat.format( "user {0} is not authorized to clone {1}", user.username, repository)); return false; } } } return true; }
protected boolean isLocalAccount(String username) { UserModel user = getUserModel(username); return user != null && user.isLocalAccount(); }
protected void setupPage(RepositoryModel model) { this.repositoryModel = model; // ensure this user can create or edit this repository checkPermissions(repositoryModel); List<String> indexedBranches = new ArrayList<String>(); List<String> federationSets = new ArrayList<String>(); final List<RegistrantAccessPermission> repositoryUsers = new ArrayList<RegistrantAccessPermission>(); final List<RegistrantAccessPermission> repositoryTeams = new ArrayList<RegistrantAccessPermission>(); List<String> preReceiveScripts = new ArrayList<String>(); List<String> postReceiveScripts = new ArrayList<String>(); GitBlitWebSession session = GitBlitWebSession.get(); final UserModel user = session.getUser() == null ? UserModel.ANONYMOUS : session.getUser(); final boolean allowEditName = isCreate || isAdmin || repositoryModel.isUsersPersonalRepository(user.username); if (isCreate) { if (user.canAdmin()) { super.setupPage(getString("gb.newRepository"), ""); } else { super.setupPage(getString("gb.newRepository"), user.getDisplayName()); } } else { super.setupPage(getString("gb.edit"), repositoryModel.name); repositoryUsers.addAll(GitBlit.self().getUserAccessPermissions(repositoryModel)); repositoryTeams.addAll(GitBlit.self().getTeamAccessPermissions(repositoryModel)); Collections.sort(repositoryUsers); Collections.sort(repositoryTeams); federationSets.addAll(repositoryModel.federationSets); if (!ArrayUtils.isEmpty(repositoryModel.indexedBranches)) { indexedBranches.addAll(repositoryModel.indexedBranches); } } final String oldName = repositoryModel.name; final RegistrantPermissionsPanel usersPalette = new RegistrantPermissionsPanel( "users", RegistrantType.USER, GitBlit.self().getAllUsernames(), repositoryUsers, getAccessPermissions()); final RegistrantPermissionsPanel teamsPalette = new RegistrantPermissionsPanel( "teams", RegistrantType.TEAM, GitBlit.self().getAllTeamnames(), repositoryTeams, getAccessPermissions()); // owners palette List<String> owners = new ArrayList<String>(repositoryModel.owners); List<String> persons = GitBlit.self().getAllUsernames(); final Palette<String> ownersPalette = new Palette<String>( "owners", new ListModel<String>(owners), new CollectionModel<String>(persons), new StringChoiceRenderer(), 12, true); // indexed local branches palette List<String> allLocalBranches = new ArrayList<String>(); allLocalBranches.add(Constants.DEFAULT_BRANCH); allLocalBranches.addAll(repositoryModel.getLocalBranches()); boolean luceneEnabled = GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true); final Palette<String> indexedBranchesPalette = new Palette<String>( "indexedBranches", new ListModel<String>(indexedBranches), new CollectionModel<String>(allLocalBranches), new StringChoiceRenderer(), 8, false); indexedBranchesPalette.setEnabled(luceneEnabled); // federation sets palette List<String> sets = GitBlit.getStrings(Keys.federation.sets); final Palette<String> federationSetsPalette = new Palette<String>( "federationSets", new ListModel<String>(federationSets), new CollectionModel<String>(sets), new StringChoiceRenderer(), 8, false); // pre-receive palette if (!ArrayUtils.isEmpty(repositoryModel.preReceiveScripts)) { preReceiveScripts.addAll(repositoryModel.preReceiveScripts); } final Palette<String> preReceivePalette = new Palette<String>( "preReceiveScripts", new ListModel<String>(preReceiveScripts), new CollectionModel<String>(GitBlit.self().getPreReceiveScriptsUnused(repositoryModel)), new StringChoiceRenderer(), 12, true); // post-receive palette if (!ArrayUtils.isEmpty(repositoryModel.postReceiveScripts)) { postReceiveScripts.addAll(repositoryModel.postReceiveScripts); } final Palette<String> postReceivePalette = new Palette<String>( "postReceiveScripts", new ListModel<String>(postReceiveScripts), new CollectionModel<String>( GitBlit.self().getPostReceiveScriptsUnused(repositoryModel)), new StringChoiceRenderer(), 12, true); // custom fields final Map<String, String> customFieldsMap = GitBlit.getMap(Keys.groovy.customFields); List<String> customKeys = new ArrayList<String>(customFieldsMap.keySet()); final ListView<String> customFieldsListView = new ListView<String>("customFieldsListView", customKeys) { private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem<String> item) { String key = item.getModelObject(); item.add(new Label("customFieldLabel", customFieldsMap.get(key))); String value = ""; if (repositoryModel.customFields != null && repositoryModel.customFields.containsKey(key)) { value = repositoryModel.customFields.get(key); } TextField<String> field = new TextField<String>("customFieldValue", new Model<String>(value)); item.add(field); } }; customFieldsListView.setReuseItems(true); CompoundPropertyModel<RepositoryModel> rModel = new CompoundPropertyModel<RepositoryModel>(repositoryModel); Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", rModel) { private static final long serialVersionUID = 1L; @Override protected void onSubmit() { try { // confirm a repository name was entered if (repositoryModel.name == null && StringUtils.isEmpty(repositoryModel.name)) { error(getString("gb.pleaseSetRepositoryName")); return; } // ensure name is trimmed repositoryModel.name = repositoryModel.name.trim(); // automatically convert backslashes to forward slashes repositoryModel.name = repositoryModel.name.replace('\\', '/'); // Automatically replace // with / repositoryModel.name = repositoryModel.name.replace("//", "/"); // prohibit folder paths if (repositoryModel.name.startsWith("/")) { error(getString("gb.illegalLeadingSlash")); return; } if (repositoryModel.name.startsWith("../")) { error(getString("gb.illegalRelativeSlash")); return; } if (repositoryModel.name.contains("/../")) { error(getString("gb.illegalRelativeSlash")); return; } if (repositoryModel.name.endsWith("/")) { repositoryModel.name = repositoryModel.name.substring(0, repositoryModel.name.length() - 1); } // confirm valid characters in repository name Character c = StringUtils.findInvalidCharacter(repositoryModel.name); if (c != null) { error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"), c)); return; } if (user.canCreate() && !user.canAdmin() && allowEditName) { // ensure repository name begins with the user's path if (!repositoryModel.name.startsWith(user.getPersonalPath())) { error( MessageFormat.format( getString("gb.illegalPersonalRepositoryLocation"), user.getPersonalPath())); return; } if (repositoryModel.name.equals(user.getPersonalPath())) { // reset path prefix and show error repositoryModel.name = user.getPersonalPath() + "/"; error(getString("gb.pleaseSetRepositoryName")); return; } } // confirm access restriction selection if (repositoryModel.accessRestriction == null) { error(getString("gb.selectAccessRestriction")); return; } // confirm federation strategy selection if (repositoryModel.federationStrategy == null) { error(getString("gb.selectFederationStrategy")); return; } // save federation set preferences if (repositoryModel.federationStrategy.exceeds(FederationStrategy.EXCLUDE)) { repositoryModel.federationSets.clear(); Iterator<String> sets = federationSetsPalette.getSelectedChoices(); while (sets.hasNext()) { repositoryModel.federationSets.add(sets.next()); } } // set author metric exclusions String ax = metricAuthorExclusions.getObject(); if (!StringUtils.isEmpty(ax)) { Set<String> list = new HashSet<String>(); for (String exclusion : StringUtils.getStringsFromValue(ax, " ")) { if (StringUtils.isEmpty(exclusion)) { continue; } if (exclusion.indexOf(' ') > -1) { list.add("\"" + exclusion + "\""); } else { list.add(exclusion); } } repositoryModel.metricAuthorExclusions = new ArrayList<String>(list); } // set mailing lists String ml = mailingLists.getObject(); if (!StringUtils.isEmpty(ml)) { Set<String> list = new HashSet<String>(); for (String address : ml.split("(,|\\s)")) { if (StringUtils.isEmpty(address)) { continue; } list.add(address.toLowerCase()); } repositoryModel.mailingLists = new ArrayList<String>(list); } // indexed branches List<String> indexedBranches = new ArrayList<String>(); Iterator<String> branches = indexedBranchesPalette.getSelectedChoices(); while (branches.hasNext()) { indexedBranches.add(branches.next()); } repositoryModel.indexedBranches = indexedBranches; // owners repositoryModel.owners.clear(); Iterator<String> owners = ownersPalette.getSelectedChoices(); while (owners.hasNext()) { repositoryModel.addOwner(owners.next()); } // pre-receive scripts List<String> preReceiveScripts = new ArrayList<String>(); Iterator<String> pres = preReceivePalette.getSelectedChoices(); while (pres.hasNext()) { preReceiveScripts.add(pres.next()); } repositoryModel.preReceiveScripts = preReceiveScripts; // post-receive scripts List<String> postReceiveScripts = new ArrayList<String>(); Iterator<String> post = postReceivePalette.getSelectedChoices(); while (post.hasNext()) { postReceiveScripts.add(post.next()); } repositoryModel.postReceiveScripts = postReceiveScripts; // custom fields repositoryModel.customFields = new LinkedHashMap<String, String>(); for (int i = 0; i < customFieldsListView.size(); i++) { ListItem<String> child = (ListItem<String>) customFieldsListView.get(i); String key = child.getModelObject(); TextField<String> field = (TextField<String>) child.get("customFieldValue"); String value = field.getValue(); repositoryModel.customFields.put(key, value); } // save the repository GitBlit.self().updateRepositoryModel(oldName, repositoryModel, isCreate); // repository access permissions if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { GitBlit.self().setUserAccessPermissions(repositoryModel, repositoryUsers); GitBlit.self().setTeamAccessPermissions(repositoryModel, repositoryTeams); } } catch (GitBlitException e) { error(e.getMessage()); return; } setRedirect(false); setResponsePage(RepositoriesPage.class); } }; // do not let the browser pre-populate these fields form.add(new SimpleAttributeModifier("autocomplete", "off")); // field names reflective match RepositoryModel fields form.add(new TextField<String>("name").setEnabled(allowEditName)); form.add(new TextField<String>("description")); form.add(ownersPalette); form.add( new CheckBox("allowForks").setEnabled(GitBlit.getBoolean(Keys.web.allowForking, true))); DropDownChoice<AccessRestrictionType> accessRestriction = new DropDownChoice<AccessRestrictionType>( "accessRestriction", Arrays.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer()); form.add(accessRestriction); form.add(new CheckBox("isFrozen")); // TODO enable origin definition form.add(new TextField<String>("origin").setEnabled(false /* isCreate */)); // allow relinking HEAD to a branch or tag other than master on edit repository List<String> availableRefs = new ArrayList<String>(); if (!ArrayUtils.isEmpty(repositoryModel.availableRefs)) { availableRefs.addAll(repositoryModel.availableRefs); } form.add( new DropDownChoice<String>("HEAD", availableRefs).setEnabled(availableRefs.size() > 0)); boolean gcEnabled = GitBlit.getBoolean(Keys.git.enableGarbageCollection, false); List<Integer> gcPeriods = Arrays.asList(1, 2, 3, 4, 5, 7, 10, 14); form.add( new DropDownChoice<Integer>("gcPeriod", gcPeriods, new GCPeriodRenderer()) .setEnabled(gcEnabled)); form.add(new TextField<String>("gcThreshold").setEnabled(gcEnabled)); // federation strategies - remove ORIGIN choice if this repository has // no origin. List<FederationStrategy> federationStrategies = new ArrayList<FederationStrategy>(Arrays.asList(FederationStrategy.values())); if (StringUtils.isEmpty(repositoryModel.origin)) { federationStrategies.remove(FederationStrategy.FEDERATE_ORIGIN); } form.add( new DropDownChoice<FederationStrategy>( "federationStrategy", federationStrategies, new FederationTypeRenderer())); form.add(new CheckBox("useTickets")); form.add(new CheckBox("useDocs")); form.add(new CheckBox("useIncrementalPushTags")); form.add(new CheckBox("showRemoteBranches")); form.add(new CheckBox("showReadme")); form.add(new CheckBox("skipSizeCalculation")); form.add(new CheckBox("skipSummaryMetrics")); List<Integer> maxActivityCommits = Arrays.asList(-1, 0, 25, 50, 75, 100, 150, 200, 250, 500); form.add( new DropDownChoice<Integer>( "maxActivityCommits", maxActivityCommits, new MaxActivityCommitsRenderer())); metricAuthorExclusions = new Model<String>( ArrayUtils.isEmpty(repositoryModel.metricAuthorExclusions) ? "" : StringUtils.flattenStrings(repositoryModel.metricAuthorExclusions, " ")); form.add(new TextField<String>("metricAuthorExclusions", metricAuthorExclusions)); mailingLists = new Model<String>( ArrayUtils.isEmpty(repositoryModel.mailingLists) ? "" : StringUtils.flattenStrings(repositoryModel.mailingLists, " ")); form.add(new TextField<String>("mailingLists", mailingLists)); form.add(indexedBranchesPalette); List<AuthorizationControl> acList = Arrays.asList(AuthorizationControl.values()); final RadioChoice<AuthorizationControl> authorizationControl = new RadioChoice<Constants.AuthorizationControl>( "authorizationControl", acList, new AuthorizationControlRenderer()); form.add(authorizationControl); final CheckBox verifyCommitter = new CheckBox("verifyCommitter"); verifyCommitter.setOutputMarkupId(true); form.add(verifyCommitter); form.add(usersPalette); form.add(teamsPalette); form.add(federationSetsPalette); form.add(preReceivePalette); form.add( new BulletListPanel( "inheritedPreReceive", getString("gb.inherited"), GitBlit.self().getPreReceiveScriptsInherited(repositoryModel))); form.add(postReceivePalette); form.add( new BulletListPanel( "inheritedPostReceive", getString("gb.inherited"), GitBlit.self().getPostReceiveScriptsInherited(repositoryModel))); WebMarkupContainer customFieldsSection = new WebMarkupContainer("customFieldsSection"); customFieldsSection.add(customFieldsListView); form.add( customFieldsSection.setVisible(!GitBlit.getString(Keys.groovy.customFields, "").isEmpty())); // initial enable/disable of permission controls if (repositoryModel.accessRestriction.equals(AccessRestrictionType.NONE)) { // anonymous everything, disable all controls usersPalette.setEnabled(false); teamsPalette.setEnabled(false); authorizationControl.setEnabled(false); verifyCommitter.setEnabled(false); } else { // authenticated something // enable authorization controls authorizationControl.setEnabled(true); verifyCommitter.setEnabled(true); boolean allowFineGrainedControls = repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED); usersPalette.setEnabled(allowFineGrainedControls); teamsPalette.setEnabled(allowFineGrainedControls); } accessRestriction.add( new AjaxFormComponentUpdatingBehavior("onchange") { private static final long serialVersionUID = 1L; protected void onUpdate(AjaxRequestTarget target) { // enable/disable permissions panel based on access restriction boolean allowAuthorizationControl = repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE); authorizationControl.setEnabled(allowAuthorizationControl); verifyCommitter.setEnabled(allowAuthorizationControl); boolean allowFineGrainedControls = allowAuthorizationControl && repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED); usersPalette.setEnabled(allowFineGrainedControls); teamsPalette.setEnabled(allowFineGrainedControls); if (allowFineGrainedControls) { repositoryModel.authorizationControl = AuthorizationControl.NAMED; } target.addComponent(authorizationControl); target.addComponent(verifyCommitter); target.addComponent(usersPalette); target.addComponent(teamsPalette); } }); authorizationControl.add( new AjaxFormChoiceComponentUpdatingBehavior() { private static final long serialVersionUID = 1L; protected void onUpdate(AjaxRequestTarget target) { // enable/disable permissions panel based on access restriction boolean allowAuthorizationControl = repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE); authorizationControl.setEnabled(allowAuthorizationControl); boolean allowFineGrainedControls = allowAuthorizationControl && repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED); usersPalette.setEnabled(allowFineGrainedControls); teamsPalette.setEnabled(allowFineGrainedControls); if (allowFineGrainedControls) { repositoryModel.authorizationControl = AuthorizationControl.NAMED; } target.addComponent(authorizationControl); target.addComponent(usersPalette); target.addComponent(teamsPalette); } }); form.add(new Button("save")); Button cancel = new Button("cancel") { private static final long serialVersionUID = 1L; @Override public void onSubmit() { setResponsePage(RepositoriesPage.class); } }; cancel.setDefaultFormProcessing(false); form.add(cancel); add(form); }
private void setup(PageParameters params) { setupPage("", ""); // check to see if we should display a login message boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true); if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) { authenticationError("Please login"); return; } String userName = WicketUtils.getUsername(params); if (StringUtils.isEmpty(userName)) { throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage()); } UserModel user = app().users().getUserModel(userName); if (user == null) { // construct a temporary user model user = new UserModel(userName); } add(new UserTitlePanel("userTitlePanel", user, user.username)); UserModel sessionUser = GitBlitWebSession.get().getUser(); boolean isMyProfile = sessionUser != null && sessionUser.equals(user); if (isMyProfile) { addPreferences(user); if (app().services().isServingSSH()) { // show the SSH key management tab addSshKeys(user); } else { // SSH daemon is disabled, hide keys tab add(new Label("sshKeysLink").setVisible(false)); add(new Label("sshKeysTab").setVisible(false)); } } else { // visiting user add(new Label("preferencesLink").setVisible(false)); add(new Label("preferencesTab").setVisible(false)); add(new Label("sshKeysLink").setVisible(false)); add(new Label("sshKeysTab").setVisible(false)); } List<RepositoryModel> repositories = getRepositories(params); Collections.sort( repositories, new Comparator<RepositoryModel>() { @Override public int compare(RepositoryModel o1, RepositoryModel o2) { // reverse-chronological sort return o2.lastChange.compareTo(o1.lastChange); } }); final ListDataProvider<RepositoryModel> dp = new ListDataProvider<RepositoryModel>(repositories); DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repositoryList", dp) { private static final long serialVersionUID = 1L; @Override public void populateItem(final Item<RepositoryModel> item) { final RepositoryModel entry = item.getModelObject(); ProjectRepositoryPanel row = new ProjectRepositoryPanel( "repository", getLocalizer(), this, showAdmin, entry, getAccessRestrictions()); item.add(row); } }; add(dataView); }
private void addPreferences(UserModel user) { // add preferences Form<Void> prefs = new Form<Void>("prefsForm"); List<Language> languages = Arrays.asList( new Language("Deutsch", "de"), new Language("English", "en"), new Language("Español", "es"), new Language("Français", "fr"), new Language("Italiano", "it"), new Language("日本語", "ja"), new Language("한국말", "ko"), new Language("Nederlands", "nl"), new Language("Norsk", "no"), new Language("Język Polski", "pl"), new Language("Português", "pt_BR"), new Language("簡體中文", "zh_CN"), new Language("正體中文", "zh_TW")); Locale locale = user.getPreferences().getLocale(); if (locale == null) { // user has not specified language preference // try server default preference String lc = app().settings().getString(Keys.web.forceDefaultLocale, null); if (StringUtils.isEmpty(lc)) { // server default language is not configured // try browser preference Locale sessionLocale = GitBlitWebSession.get().getLocale(); if (sessionLocale != null) { locale = sessionLocale; } } else { } } Language preferredLanguage = null; if (locale != null) { String localeCode = locale.getLanguage(); if (!StringUtils.isEmpty(locale.getCountry())) { localeCode += "_" + locale.getCountry(); } for (Language language : languages) { if (language.code.equals(localeCode)) { // language_COUNTRY match preferredLanguage = language; } else if (preferredLanguage != null && language.code.startsWith(locale.getLanguage())) { // language match preferredLanguage = language; } } } final IModel<String> displayName = Model.of(user.getDisplayName()); final IModel<String> emailAddress = Model.of(user.emailAddress == null ? "" : user.emailAddress); final IModel<Language> language = Model.of(preferredLanguage); final IModel<Boolean> emailMeOnMyTicketChanges = Model.of(user.getPreferences().isEmailMeOnMyTicketChanges()); final IModel<Transport> transport = Model.of(user.getPreferences().getTransport()); prefs.add( new TextOption( "displayName", getString("gb.displayName"), getString("gb.displayNameDescription"), displayName) .setVisible(app().authentication().supportsDisplayNameChanges(user))); prefs.add( new TextOption( "emailAddress", getString("gb.emailAddress"), getString("gb.emailAddressDescription"), emailAddress) .setVisible(app().authentication().supportsEmailAddressChanges(user))); prefs.add( new ChoiceOption<Language>( "language", getString("gb.languagePreference"), getString("gb.languagePreferenceDescription"), language, languages)); prefs.add( new BooleanOption( "emailMeOnMyTicketChanges", getString("gb.emailMeOnMyTicketChanges"), getString("gb.emailMeOnMyTicketChangesDescription"), emailMeOnMyTicketChanges) .setVisible(app().notifier().isSendingMail())); List<Transport> availableTransports = new ArrayList<>(); if (app().services().isServingSSH()) { availableTransports.add(Transport.SSH); } if (app().services().isServingHTTP()) { availableTransports.add(Transport.HTTP); } if (app().services().isServingHTTPS()) { availableTransports.add(Transport.HTTPS); } if (app().services().isServingGIT()) { availableTransports.add(Transport.GIT); } prefs.add( new ChoiceOption<Transport>( "transport", getString("gb.transportPreference"), getString("gb.transportPreferenceDescription"), transport, availableTransports)); prefs.add( new AjaxButton("save") { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { UserModel user = GitBlitWebSession.get().getUser(); user.displayName = displayName.getObject(); user.emailAddress = emailAddress.getObject(); Language lang = language.getObject(); if (lang != null) { user.getPreferences().setLocale(lang.code); } user.getPreferences().setEmailMeOnMyTicketChanges(emailMeOnMyTicketChanges.getObject()); user.getPreferences().setTransport(transport.getObject()); try { app().gitblit().reviseUser(user.username, user); setRedirect(true); setResponsePage(UserPage.class, WicketUtils.newUsernameParameter(user.username)); } catch (GitBlitException e) { // logger.error("Failed to update user " + user.username, e); // error(getString("gb.failedToUpdateUser"), false); } } }); // add the preferences tab add(new Fragment("preferencesLink", "preferencesLinkFragment", this).setRenderBodyOnly(true)); Fragment fragment = new Fragment("preferencesTab", "preferencesTabFragment", this); fragment.add(prefs); add(fragment.setRenderBodyOnly(true)); }
public BranchesPanel( String wicketId, final RepositoryModel model, Repository r, final int maxCount, final boolean showAdmin) { super(wicketId); // branches List<RefModel> branches = new ArrayList<RefModel>(); UserModel user = GitBlitWebSession.get().getUser(); if (user == null) { user = UserModel.ANONYMOUS; } List<RefModel> localBranches = JGitUtils.getLocalBranches(r, false, -1); for (RefModel refModel : localBranches) { if (user.canView(model, refModel.reference.getName())) { branches.add(refModel); } } if (model.showRemoteBranches) { List<RefModel> remoteBranches = JGitUtils.getRemoteBranches(r, false, -1); for (RefModel refModel : remoteBranches) { if (user.canView(model, refModel.reference.getName())) { branches.add(refModel); } } } Collections.sort(branches); Collections.reverse(branches); if (maxCount > 0 && branches.size() > maxCount) { branches = new ArrayList<RefModel>(branches.subList(0, maxCount)); } if (maxCount > 0) { // summary page // show branches page link add( new LinkPanel( "branches", "title", new StringResourceModel("gb.branches", this, null), BranchesPage.class, WicketUtils.newRepositoryParameter(model.name))); } else { // branches page add(new Label("branches", new StringResourceModel("gb.branches", this, null))); } // only allow delete if we have multiple branches final boolean showDelete = showAdmin && branches.size() > 1; ListDataProvider<RefModel> branchesDp = new ListDataProvider<RefModel>(branches); DataView<RefModel> branchesView = new DataView<RefModel>("branch", branchesDp) { private static final long serialVersionUID = 1L; int counter; public void populateItem(final Item<RefModel> item) { final RefModel entry = item.getModelObject(); item.add( WicketUtils.createDateLabel( "branchDate", entry.getDate(), getTimeZone(), getTimeUtils())); item.add( new LinkPanel( "branchName", "list name", StringUtils.trimString(entry.displayName, 28), LogPage.class, WicketUtils.newObjectParameter(model.name, entry.getName()))); String author = entry.getAuthorIdent().getName(); LinkPanel authorLink = new LinkPanel( "branchAuthor", "list", author, GitSearchPage.class, WicketUtils.newSearchParameter( model.name, entry.getName(), author, Constants.SearchType.AUTHOR)); setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR); item.add(authorLink); // short message String shortMessage = entry.getShortMessage(); String trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); LinkPanel shortlog = new LinkPanel( "branchLog", "list subject", trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(model.name, entry.getName())); if (!shortMessage.equals(trimmedMessage)) { WicketUtils.setHtmlTooltip(shortlog, shortMessage); } item.add(shortlog); if (maxCount <= 0) { Fragment fragment = new Fragment( "branchLinks", showDelete ? "branchPageAdminLinks" : "branchPageLinks", this); fragment.add( new BookmarkablePageLink<Void>( "log", LogPage.class, WicketUtils.newObjectParameter(model.name, entry.getName()))); fragment.add( new BookmarkablePageLink<Void>( "tree", TreePage.class, WicketUtils.newObjectParameter(model.name, entry.getName()))); fragment.add( new BookmarkablePageLink<Void>( "metrics", MetricsPage.class, WicketUtils.newObjectParameter(model.name, entry.getName()))); fragment.add( new ExternalLink( "syndication", SyndicationServlet.asLink( getRequest().getRelativePathPrefixToContextRoot(), model.name, entry.getName(), 0))); if (showDelete) { fragment.add(createDeleteBranchLink(model, entry)); } item.add(fragment); } else { Fragment fragment = new Fragment("branchLinks", "branchPanelLinks", this); fragment.add( new BookmarkablePageLink<Void>( "log", LogPage.class, WicketUtils.newObjectParameter(model.name, entry.getName()))); fragment.add( new BookmarkablePageLink<Void>( "tree", TreePage.class, WicketUtils.newObjectParameter(model.name, entry.getName()))); item.add(fragment); } WicketUtils.setAlternatingBackground(item, counter); counter++; } }; add(branchesView); if (branches.size() < maxCount || maxCount <= 0) { add(new Label("allBranches", "").setVisible(false)); } else { add( new LinkPanel( "allBranches", "link", new StringResourceModel("gb.allBranches", this, null), BranchesPage.class, WicketUtils.newRepositoryParameter(model.name))); } // We always have 1 branch hasBranches = (branches.size() > 1) || ((branches.size() == 1) && !branches.get(0).displayName.equalsIgnoreCase("master")); }
private void setup(PageParameters params) { setupPage("", ""); // check to see if we should display a login message boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true); if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) { authenticationError("Please login"); return; } String projectName = WicketUtils.getProjectName(params); if (StringUtils.isEmpty(projectName)) { throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage()); } ProjectModel project = getProjectModel(projectName); if (project == null) { throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage()); } add(new Label("projectTitle", project.getDisplayName())); add(new Label("projectDescription", project.description)); String feedLink = SyndicationServlet.asLink( getRequest().getRelativePathPrefixToContextRoot(), projectName, null, 0); add(new ExternalLink("syndication", feedLink)); add( WicketUtils.syndicationDiscoveryLink( SyndicationServlet.getTitle(project.getDisplayName(), null), feedLink)); // project markdown message String pmessage = transformMarkdown(project.projectMarkdown); Component projectMessage = new Label("projectMessage", pmessage) .setEscapeModelStrings(false) .setVisible(pmessage.length() > 0); add(projectMessage); // markdown message above repositories list String rmessage = transformMarkdown(project.repositoriesMarkdown); Component repositoriesMessage = new Label("repositoriesMessage", rmessage) .setEscapeModelStrings(false) .setVisible(rmessage.length() > 0); add(repositoriesMessage); UserModel user = GitBlitWebSession.get().getUser(); if (user == null) { user = UserModel.ANONYMOUS; } int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params); if (daysBack < 1) { daysBack = GitBlit.getInteger(Keys.web.activityDuration, 7); } // reset the daysback parameter so that we have a complete project // repository list. the recent activity will be built up by the // reflog utils. params.remove("db"); List<RepositoryModel> repositories = getRepositories(params); Collections.sort( repositories, new Comparator<RepositoryModel>() { @Override public int compare(RepositoryModel o1, RepositoryModel o2) { // reverse-chronological sort return o2.lastChange.compareTo(o1.lastChange); } }); addActivity(user, repositories, getString("gb.recentActivity"), daysBack); if (repositories.isEmpty()) { add(new Label("repositoryList").setVisible(false)); } else { FilterableRepositoryList repoList = new FilterableRepositoryList("repositoryList", repositories); repoList.setAllowCreate(user.canCreate(project.name + "/")); add(repoList); } }
/** * Mirrors a repository and, optionally, the server's users, and/or configuration settings from a * origin Gitblit instance. * * @param registration * @throws Exception */ private void pull(FederationModel registration) throws Exception { Map<String, RepositoryModel> repositories = FederationUtils.getRepositories(registration, true); String registrationFolder = registration.folder.toLowerCase().trim(); // confirm valid characters in server alias Character c = StringUtils.findInvalidCharacter(registrationFolder); if (c != null) { logger.error( MessageFormat.format( "Illegal character ''{0}'' in folder name ''{1}'' of federation registration {2}!", c, registrationFolder, registration.name)); return; } File repositoriesFolder = new File(GitBlit.getString(Keys.git.repositoriesFolder, "git")); File registrationFolderFile = new File(repositoriesFolder, registrationFolder); registrationFolderFile.mkdirs(); // Clone/Pull the repository for (Map.Entry<String, RepositoryModel> entry : repositories.entrySet()) { String cloneUrl = entry.getKey(); RepositoryModel repository = entry.getValue(); if (!repository.hasCommits) { logger.warn( MessageFormat.format( "Skipping federated repository {0} from {1} @ {2}. Repository is EMPTY.", repository.name, registration.name, registration.url)); registration.updateStatus(repository, FederationPullStatus.SKIPPED); continue; } // Determine local repository name String repositoryName; if (StringUtils.isEmpty(registrationFolder)) { repositoryName = repository.name; } else { repositoryName = registrationFolder + "/" + repository.name; } if (registration.bare) { // bare repository, ensure .git suffix if (!repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) { repositoryName += DOT_GIT_EXT; } } else { // normal repository, strip .git suffix if (repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) { repositoryName = repositoryName.substring(0, repositoryName.indexOf(DOT_GIT_EXT)); } } // confirm that the origin of any pre-existing repository matches // the clone url String fetchHead = null; Repository existingRepository = GitBlit.self().getRepository(repositoryName); if (existingRepository == null && GitBlit.self().isCollectingGarbage(repositoryName)) { logger.warn( MessageFormat.format( "Skipping local repository {0}, busy collecting garbage", repositoryName)); continue; } if (existingRepository != null) { StoredConfig config = existingRepository.getConfig(); config.load(); String origin = config.getString("remote", "origin", "url"); RevCommit commit = JGitUtils.getCommit(existingRepository, org.eclipse.jgit.lib.Constants.FETCH_HEAD); if (commit != null) { fetchHead = commit.getName(); } existingRepository.close(); if (!origin.startsWith(registration.url)) { logger.warn( MessageFormat.format( "Skipping federated repository {0} from {1} @ {2}. Origin does not match, consider EXCLUDING.", repository.name, registration.name, registration.url)); registration.updateStatus(repository, FederationPullStatus.SKIPPED); continue; } } // clone/pull this repository CredentialsProvider credentials = new UsernamePasswordCredentialsProvider(Constants.FEDERATION_USER, registration.token); logger.info( MessageFormat.format( "Pulling federated repository {0} from {1} @ {2}", repository.name, registration.name, registration.url)); CloneResult result = JGitUtils.cloneRepository( registrationFolderFile, repository.name, cloneUrl, registration.bare, credentials); Repository r = GitBlit.self().getRepository(repositoryName); RepositoryModel rm = GitBlit.self().getRepositoryModel(repositoryName); repository.isFrozen = registration.mirror; if (result.createdRepository) { // default local settings repository.federationStrategy = FederationStrategy.EXCLUDE; repository.isFrozen = registration.mirror; repository.showRemoteBranches = !registration.mirror; logger.info(MessageFormat.format(" cloning {0}", repository.name)); registration.updateStatus(repository, FederationPullStatus.MIRRORED); } else { // fetch and update boolean fetched = false; RevCommit commit = JGitUtils.getCommit(r, org.eclipse.jgit.lib.Constants.FETCH_HEAD); String newFetchHead = commit.getName(); fetched = fetchHead == null || !fetchHead.equals(newFetchHead); if (registration.mirror) { // mirror if (fetched) { // update local branches to match the remote tracking branches for (RefModel ref : JGitUtils.getRemoteBranches(r, false, -1)) { if (ref.displayName.startsWith("origin/")) { String branch = org.eclipse.jgit.lib.Constants.R_HEADS + ref.displayName.substring(ref.displayName.indexOf('/') + 1); String hash = ref.getReferencedObjectId().getName(); JGitUtils.setBranchRef(r, branch, hash); logger.info( MessageFormat.format( " resetting {0} of {1} to {2}", branch, repository.name, hash)); } } String newHead; if (StringUtils.isEmpty(repository.HEAD)) { newHead = newFetchHead; } else { newHead = repository.HEAD; } JGitUtils.setHEADtoRef(r, newHead); logger.info( MessageFormat.format( " resetting HEAD of {0} to {1}", repository.name, newHead)); registration.updateStatus(repository, FederationPullStatus.MIRRORED); } else { // indicate no commits pulled registration.updateStatus(repository, FederationPullStatus.NOCHANGE); } } else { // non-mirror if (fetched) { // indicate commits pulled to origin/master registration.updateStatus(repository, FederationPullStatus.PULLED); } else { // indicate no commits pulled registration.updateStatus(repository, FederationPullStatus.NOCHANGE); } } // preserve local settings repository.isFrozen = rm.isFrozen; repository.federationStrategy = rm.federationStrategy; // merge federation sets Set<String> federationSets = new HashSet<String>(); if (rm.federationSets != null) { federationSets.addAll(rm.federationSets); } if (repository.federationSets != null) { federationSets.addAll(repository.federationSets); } repository.federationSets = new ArrayList<String>(federationSets); // merge indexed branches Set<String> indexedBranches = new HashSet<String>(); if (rm.indexedBranches != null) { indexedBranches.addAll(rm.indexedBranches); } if (repository.indexedBranches != null) { indexedBranches.addAll(repository.indexedBranches); } repository.indexedBranches = new ArrayList<String>(indexedBranches); } // only repositories that are actually _cloned_ from the origin // Gitblit repository are marked as federated. If the origin // is from somewhere else, these repositories are not considered // "federated" repositories. repository.isFederated = cloneUrl.startsWith(registration.url); GitBlit.self().updateConfiguration(r, repository); r.close(); } IUserService userService = null; try { // Pull USERS // TeamModels are automatically pulled because they are contained // within the UserModel. The UserService creates unknown teams // and updates existing teams. Collection<UserModel> users = FederationUtils.getUsers(registration); if (users != null && users.size() > 0) { File realmFile = new File(registrationFolderFile, registration.name + "_users.conf"); realmFile.delete(); userService = new ConfigUserService(realmFile); for (UserModel user : users) { userService.updateUserModel(user.username, user); // merge the origin permissions and origin accounts into // the user accounts of this Gitblit instance if (registration.mergeAccounts) { // reparent all repository permissions if the local // repositories are stored within subfolders if (!StringUtils.isEmpty(registrationFolder)) { if (user.permissions != null) { // pulling from >= 1.2 version Map<String, AccessPermission> copy = new HashMap<String, AccessPermission>(user.permissions); user.permissions.clear(); for (Map.Entry<String, AccessPermission> entry : copy.entrySet()) { user.setRepositoryPermission( registrationFolder + "/" + entry.getKey(), entry.getValue()); } } else { // pulling from <= 1.1 version List<String> permissions = new ArrayList<String>(user.repositories); user.repositories.clear(); for (String permission : permissions) { user.addRepositoryPermission(registrationFolder + "/" + permission); } } } // insert new user or update local user UserModel localUser = GitBlit.self().getUserModel(user.username); if (localUser == null) { // create new local user GitBlit.self().updateUserModel(user.username, user, true); } else { // update repository permissions of local user if (user.permissions != null) { // pulling from >= 1.2 version Map<String, AccessPermission> copy = new HashMap<String, AccessPermission>(user.permissions); for (Map.Entry<String, AccessPermission> entry : copy.entrySet()) { localUser.setRepositoryPermission(entry.getKey(), entry.getValue()); } } else { // pulling from <= 1.1 version for (String repository : user.repositories) { localUser.addRepositoryPermission(repository); } } localUser.password = user.password; localUser.canAdmin = user.canAdmin; GitBlit.self().updateUserModel(localUser.username, localUser, false); } for (String teamname : GitBlit.self().getAllTeamnames()) { TeamModel team = GitBlit.self().getTeamModel(teamname); if (user.isTeamMember(teamname) && !team.hasUser(user.username)) { // new team member team.addUser(user.username); GitBlit.self().updateTeamModel(teamname, team, false); } else if (!user.isTeamMember(teamname) && team.hasUser(user.username)) { // remove team member team.removeUser(user.username); GitBlit.self().updateTeamModel(teamname, team, false); } // update team repositories TeamModel remoteTeam = user.getTeam(teamname); if (remoteTeam != null) { if (remoteTeam.permissions != null) { // pulling from >= 1.2 for (Map.Entry<String, AccessPermission> entry : remoteTeam.permissions.entrySet()) { team.setRepositoryPermission(entry.getKey(), entry.getValue()); } GitBlit.self().updateTeamModel(teamname, team, false); } else if (!ArrayUtils.isEmpty(remoteTeam.repositories)) { // pulling from <= 1.1 team.addRepositoryPermissions(remoteTeam.repositories); GitBlit.self().updateTeamModel(teamname, team, false); } } } } } } } catch (ForbiddenException e) { // ignore forbidden exceptions } catch (IOException e) { logger.warn( MessageFormat.format( "Failed to retrieve USERS from federated gitblit ({0} @ {1})", registration.name, registration.url), e); } try { // Pull TEAMS // We explicitly pull these even though they are embedded in // UserModels because it is possible to use teams to specify // mailing lists or push scripts without specifying users. if (userService != null) { Collection<TeamModel> teams = FederationUtils.getTeams(registration); if (teams != null && teams.size() > 0) { for (TeamModel team : teams) { userService.updateTeamModel(team); } } } } catch (ForbiddenException e) { // ignore forbidden exceptions } catch (IOException e) { logger.warn( MessageFormat.format( "Failed to retrieve TEAMS from federated gitblit ({0} @ {1})", registration.name, registration.url), e); } try { // Pull SETTINGS Map<String, String> settings = FederationUtils.getSettings(registration); if (settings != null && settings.size() > 0) { Properties properties = new Properties(); properties.putAll(settings); FileOutputStream os = new FileOutputStream( new File( registrationFolderFile, registration.name + "_" + Constants.PROPERTIES_FILE)); properties.store(os, null); os.close(); } } catch (ForbiddenException e) { // ignore forbidden exceptions } catch (IOException e) { logger.warn( MessageFormat.format( "Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})", registration.name, registration.url), e); } try { // Pull SCRIPTS Map<String, String> scripts = FederationUtils.getScripts(registration); if (scripts != null && scripts.size() > 0) { for (Map.Entry<String, String> script : scripts.entrySet()) { String scriptName = script.getKey(); if (scriptName.endsWith(".groovy")) { scriptName = scriptName.substring(0, scriptName.indexOf(".groovy")); } File file = new File(registrationFolderFile, registration.name + "_" + scriptName + ".groovy"); FileUtils.writeContent(file, script.getValue()); } } } catch (ForbiddenException e) { // ignore forbidden exceptions } catch (IOException e) { logger.warn( MessageFormat.format( "Failed to retrieve SCRIPTS from federated gitblit ({0} @ {1})", registration.name, registration.url), e); } }
private void setup(PageParameters params) { setupPage("", ""); // check to see if we should display a login message boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true); if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) { String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit"); String message = readMarkdown(messageSource, "login.mkd"); Component repositoriesMessage = new Label("repositoriesMessage", message); add(repositoriesMessage.setEscapeModelStrings(false)); add(new Label("activity").setVisible(false)); add(new Label("repositoryTabs").setVisible(false)); return; } // Load the markdown welcome message String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit"); String message = readMarkdown(messageSource, "welcome.mkd"); Component repositoriesMessage = new Label("repositoriesMessage", message) .setEscapeModelStrings(false) .setVisible(message.length() > 0); add(repositoriesMessage); UserModel user = GitBlitWebSession.get().getUser(); if (user == null) { user = UserModel.ANONYMOUS; } // parameters int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params); if (daysBack < 1) { daysBack = GitBlit.getInteger(Keys.web.activityDuration, 7); } Calendar c = Calendar.getInstance(); c.add(Calendar.DATE, -1 * daysBack); Date minimumDate = c.getTime(); // build repo lists List<RepositoryModel> starred = new ArrayList<RepositoryModel>(); List<RepositoryModel> owned = new ArrayList<RepositoryModel>(); List<RepositoryModel> active = new ArrayList<RepositoryModel>(); for (RepositoryModel model : getRepositoryModels()) { if (model.isUsersPersonalRepository(user.username) || model.isOwner(user.username)) { owned.add(model); } if (user.getPreferences().isStarredRepository(model.name)) { starred.add(model); } if (model.isShowActivity() && model.lastChange.after(minimumDate)) { active.add(model); } } Comparator<RepositoryModel> lastUpdateSort = new Comparator<RepositoryModel>() { @Override public int compare(RepositoryModel o1, RepositoryModel o2) { return o2.lastChange.compareTo(o1.lastChange); } }; Collections.sort(owned, lastUpdateSort); Collections.sort(starred, lastUpdateSort); Collections.sort(active, lastUpdateSort); String activityTitle; Set<RepositoryModel> feed = new HashSet<RepositoryModel>(); feed.addAll(starred); feed.addAll(owned); if (feed.isEmpty()) { // no starred or owned, go with recent activity activityTitle = getString("gb.recentActivity"); feed.addAll(active); } else if (starred.isEmpty()) { // no starred, owned repos feed activityTitle = getString("gb.owned"); } else if (owned.isEmpty()) { // no owned, starred repos feed activityTitle = getString("gb.starred"); } else { // starred and owned repositories activityTitle = getString("gb.starredAndOwned"); } addActivity(user, feed, activityTitle, daysBack); Fragment repositoryTabs; if (UserModel.ANONYMOUS.equals(user)) { repositoryTabs = new Fragment("repositoryTabs", "anonymousTabsFragment", this); } else { repositoryTabs = new Fragment("repositoryTabs", "authenticatedTabsFragment", this); } add(repositoryTabs); // projects list List<ProjectModel> projects = GitBlit.self().getProjectModels(getRepositoryModels(), false); repositoryTabs.add(new FilterableProjectList("projects", projects)); // active repository list if (active.isEmpty()) { repositoryTabs.add(new Label("active").setVisible(false)); } else { FilterableRepositoryList repoList = new FilterableRepositoryList("active", active); repoList.setTitle(getString("gb.activeRepositories"), "icon-time"); repositoryTabs.add(repoList); } // starred repository list if (ArrayUtils.isEmpty(starred)) { repositoryTabs.add(new Label("starred").setVisible(false)); } else { FilterableRepositoryList repoList = new FilterableRepositoryList("starred", starred); repoList.setTitle(getString("gb.starredRepositories"), "icon-star"); repositoryTabs.add(repoList); } // owned repository list if (ArrayUtils.isEmpty(owned)) { repositoryTabs.add(new Label("owned").setVisible(false)); } else { FilterableRepositoryList repoList = new FilterableRepositoryList("owned", owned); repoList.setTitle(getString("gb.myRepositories"), "icon-user"); repoList.setAllowCreate(user.canCreate() || user.canAdmin()); repositoryTabs.add(repoList); } }
protected void setupPage(final UserModel userModel) { if (isCreate) { super.setupPage(getString("gb.newUser"), ""); } else { super.setupPage(getString("gb.edit"), userModel.username); } final Model<String> confirmPassword = new Model<String>(StringUtils.isEmpty(userModel.password) ? "" : userModel.password); CompoundPropertyModel<UserModel> model = new CompoundPropertyModel<UserModel>(userModel); // build list of projects including all repositories wildcards List<String> repos = getAccessRestrictedRepositoryList(true, userModel); List<String> userTeams = new ArrayList<String>(); for (TeamModel team : userModel.getTeams()) { userTeams.add(team.name); } Collections.sort(userTeams); final String oldName = userModel.username; final List<RegistrantAccessPermission> permissions = app().repositories().getUserAccessPermissions(userModel); final Palette<String> teams = new Palette<String>( "teams", new ListModel<String>(new ArrayList<String>(userTeams)), new CollectionModel<String>(app().users().getAllTeamNames()), new StringChoiceRenderer(), 10, false); Form<UserModel> form = new Form<UserModel>("editForm", model) { private static final long serialVersionUID = 1L; /* * (non-Javadoc) * * @see org.apache.wicket.markup.html.form.Form#onSubmit() */ @Override protected void onSubmit() { if (StringUtils.isEmpty(userModel.username)) { error(getString("gb.pleaseSetUsername")); return; } // force username to lower-case userModel.username = userModel.username.toLowerCase(); String username = userModel.username; if (isCreate) { UserModel model = app().users().getUserModel(username); if (model != null) { error(MessageFormat.format(getString("gb.usernameUnavailable"), username)); return; } } boolean rename = !StringUtils.isEmpty(oldName) && !oldName.equalsIgnoreCase(username); if (app().authentication().supportsCredentialChanges(userModel)) { if (!userModel.password.equals(confirmPassword.getObject())) { error(getString("gb.passwordsDoNotMatch")); return; } String password = userModel.password; if (!password.toUpperCase().startsWith(StringUtils.MD5_TYPE) && !password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) { // This is a plain text password. // Check length. int minLength = app().settings().getInteger(Keys.realm.minPasswordLength, 5); if (minLength < 4) { minLength = 4; } if (password.trim().length() < minLength) { error(MessageFormat.format(getString("gb.passwordTooShort"), minLength)); return; } // change the cookie userModel.cookie = StringUtils.getSHA1(userModel.username + password); // Optionally store the password MD5 digest. String type = app().settings().getString(Keys.realm.passwordStorage, "md5"); if (type.equalsIgnoreCase("md5")) { // store MD5 digest of password userModel.password = StringUtils.MD5_TYPE + StringUtils.getMD5(userModel.password); } else if (type.equalsIgnoreCase("combined-md5")) { // store MD5 digest of username+password userModel.password = StringUtils.COMBINED_MD5_TYPE + StringUtils.getMD5(username + userModel.password); } } else if (rename && password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) { error(getString("gb.combinedMd5Rename")); return; } } // update user permissions for (RegistrantAccessPermission repositoryPermission : permissions) { if (repositoryPermission.mutable) { userModel.setRepositoryPermission( repositoryPermission.registrant, repositoryPermission.permission); } } Iterator<String> selectedTeams = teams.getSelectedChoices(); userModel.removeAllTeams(); while (selectedTeams.hasNext()) { TeamModel team = app().users().getTeamModel(selectedTeams.next()); if (team == null) { continue; } userModel.addTeam(team); } try { if (isCreate) { app().gitblit().addUser(userModel); } else { app().gitblit().reviseUser(oldName, userModel); } } catch (GitBlitException e) { error(e.getMessage()); return; } setRedirect(false); if (isCreate) { // create another user info(MessageFormat.format(getString("gb.userCreated"), userModel.username)); setResponsePage(EditUserPage.class); } else { // back to users page setResponsePage(UsersPage.class); } } }; // do not let the browser pre-populate these fields form.add(new SimpleAttributeModifier("autocomplete", "off")); // not all user providers support manipulating username and password boolean editCredentials = app().authentication().supportsCredentialChanges(userModel); // not all user providers support manipulating display name boolean editDisplayName = app().authentication().supportsDisplayNameChanges(userModel); // not all user providers support manipulating email address boolean editEmailAddress = app().authentication().supportsEmailAddressChanges(userModel); // not all user providers support manipulating team memberships boolean editTeams = app().authentication().supportsTeamMembershipChanges(userModel); // not all user providers support manipulating the admin role boolean changeAdminRole = app().authentication().supportsRoleChanges(userModel, Role.ADMIN); // not all user providers support manipulating the create role boolean changeCreateRole = app().authentication().supportsRoleChanges(userModel, Role.CREATE); // not all user providers support manipulating the fork role boolean changeForkRole = app().authentication().supportsRoleChanges(userModel, Role.FORK); // field names reflective match UserModel fields form.add(new TextField<String>("username").setEnabled(editCredentials)); NonTrimmedPasswordTextField passwordField = new NonTrimmedPasswordTextField("password"); passwordField.setResetPassword(false); form.add(passwordField.setEnabled(editCredentials)); NonTrimmedPasswordTextField confirmPasswordField = new NonTrimmedPasswordTextField("confirmPassword", confirmPassword); confirmPasswordField.setResetPassword(false); form.add(confirmPasswordField.setEnabled(editCredentials)); form.add(new TextField<String>("displayName").setEnabled(editDisplayName)); form.add(new TextField<String>("emailAddress").setEnabled(editEmailAddress)); if (userModel.canAdmin() && !userModel.canAdmin) { // user inherits Admin permission // display a disabled-yet-checked checkbox form.add(new CheckBox("canAdmin", Model.of(true)).setEnabled(false)); } else { form.add(new CheckBox("canAdmin").setEnabled(changeAdminRole)); } if (userModel.canFork() && !userModel.canFork) { // user inherits Fork permission // display a disabled-yet-checked checkbox form.add(new CheckBox("canFork", Model.of(true)).setEnabled(false)); } else { final boolean forkingAllowed = app().settings().getBoolean(Keys.web.allowForking, true); form.add(new CheckBox("canFork").setEnabled(forkingAllowed && changeForkRole)); } if (userModel.canCreate() && !userModel.canCreate) { // user inherits Create permission // display a disabled-yet-checked checkbox form.add(new CheckBox("canCreate", Model.of(true)).setEnabled(false)); } else { form.add(new CheckBox("canCreate").setEnabled(changeCreateRole)); } form.add(new CheckBox("excludeFromFederation")); form.add(new CheckBox("disabled")); form.add( new RegistrantPermissionsPanel( "repositories", RegistrantType.REPOSITORY, repos, permissions, getAccessPermissions())); form.add(teams.setEnabled(editTeams)); form.add(new TextField<String>("organizationalUnit").setEnabled(editDisplayName)); form.add(new TextField<String>("organization").setEnabled(editDisplayName)); form.add(new TextField<String>("locality").setEnabled(editDisplayName)); form.add(new TextField<String>("stateProvince").setEnabled(editDisplayName)); form.add(new TextField<String>("countryCode").setEnabled(editDisplayName)); form.add(new Button("save")); Button cancel = new Button("cancel") { private static final long serialVersionUID = 1L; @Override public void onSubmit() { setResponsePage(UsersPage.class); } }; cancel.setDefaultFormProcessing(false); form.add(cancel); add(form); }
public boolean canAdmin() { if (user == null) { return false; } return user.canAdmin(); }