diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d9be5bdc219713eabb49910e0f8e5be7428a562..4a773d58f26534c0387bee5147d3c06ff6827629 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,10 @@ -# Contribute to GitLab +# Reporting issues -This guide details how to use issues and pull requests to improve GitLab. +If you have issues with Public GitLab, you can report them with the Github issues module. +<<<<<<< HEAD +Please remember to provide as much information as you can (e.g. which database you are using). +======= - [Closing policy for issues and pull requests](#closing-policy-for-issues-and-pull-requests) - [Issue tracker](#issue-tracker) - [Pull requests](#pull-requests) @@ -9,67 +12,8 @@ This guide details how to use issues and pull requests to improve GitLab. If you want to know how the GitLab team handles contributions have a look at [the GitLab contributing process](PROCESS.md). ## Closing policy for issues and pull requests +>>>>>>> 0e387919c3827260434aed48e1f28ee02ce5e58d -GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice. +Disclaimer: I do not provide any support on GitLab itself. I only contribute to the _public part_. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself. -Please treat our volunteers with courtesy and respect, it will go a long way towards getting your issue resolved. - -Issues and pull requests should be in English and contain appropriate language for audiences of all ages. - -## Issue tracker - -To get support for your particular problem please use the channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). - -The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a pull request which partially or fully addresses the issue. - -Do not use the issue tracker for feature requests. We have a specific [feedback and suggestions forum](http://feedback.gitlab.com) for this purpose. - -Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there. - -### Issue tracker guidelines - -**[Search](https://github.com/gitlabhq/gitlabhq/search?q=&ref=cmdform&type=Issues)** for similar entries before submitting your own, there's a good chance somebody else had the same issue. Show your support with `:+1:` and/or join the discussion. Please submit issues in the following format (as the first post): - -1. **Summary:** Summarize your issue in one sentence (what goes wrong, what did you expect to happen) -2. **Steps to reproduce:** How can we reproduce the issue, preferably on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: `vagrant destroy && vagrant up && vagrant ssh`) -3. **Expected behavior:** Describe your issue in detail -4. **Observed behavior** -5. **Relevant logs and/or screenshots:** Please use code blocks (\`\`\`) to format console output, logs, and code as it's very hard to read otherwise. -6. **Output of checks** - * Results of GitLab [Application Check](doc/install/installation.md#check-application-status) (`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production`); we will only investigate if the tests are passing - * Version of GitLab you are running; we will only investigate issues in the latest stable and development releases as per the [maintenance policy](MAINTENANCE.md) - * Add the last commit sha1 of the GitLab version you used to replicate the issue (obtainable from the help page) - * Describe your setup (use relevant parts from `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`) -7. **Possible fixes**: If you can, link to the line of code that might be responsible for the problem - -## Pull requests - -We welcome pull requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a pull request for are listed with the [status 'accepting merge/pull requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. - -### Pull request guidelines - -If you can, please submit a pull request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a pull request is as follows: - -1. Fork the project on GitHub -1. Create a feature branch -1. Write [tests](README.md#run-the-tests) and code -1. Add your changes to the [CHANGELOG](CHANGELOG) -1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) -1. Push the commit to your fork -1. Submit a pull request -2. [Search for issues](https://github.com/gitlabhq/gitlabhq/search?q=&ref=cmdform&type=Issues) related to your pull request and mention them in the pull request description - -We will accept pull requests if: - -* The code has proper tests and all tests pass (or it is a test exposing a failure in existing code) -* It can be merged without problems (if not please use: `git rebase master`) -* It does not break any existing functionality -* It's quality code that conforms to the [Ruby](https://github.com/bbatsov/ruby-style-guide) and [Rails](https://github.com/bbatsov/rails-style-guide) style guides and best practices -* The description includes a motive for your change and the method you used to achieve it -* It is not a catch all pull request but rather fixes a specific issue or implements a specific feature -* It keeps the GitLab code base clean and well structured -* We think other users will benefit from the same functionality -* If it makes changes to the UI the pull request should include screenshots -* It is a single commit (please use `git rebase -i` to squash commits) - -For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed). +If there is a new stable branch, please do not open an issue to ask for an update. [Contact me](http://hoa.ro/static6/contact) instead. diff --git a/README.md b/README.md old mode 100644 new mode 100755 index ce0f4a8a1c5ec7d4fb351e266fd5a16716d1d08f..f938e1d5c5756919657417c02b085572c20f3b2e --- a/README.md +++ b/README.md @@ -1,166 +1,165 @@ -## GitLab: self hosted Git management software +# Public GitLab - +## Presentation - +Public GitLab is a fork of the official [GitLab](https://github.com/gitlabhq/gitlabhq) software. This fork allows you to host public repositories as long as official software does NOT support it (e.g. for Open Source projects). With this fork, I'm trying to reproduce Github behaviour. -### GitLab allows you to - * keep your code secure on your own server - * manage repositories, users and access permissions - * communicate through issues, line-comments and wiki pages - * perform code review with merge requests +So by public I mean: -### GitLab is + * Allow anonymous users to browse your public repositories. + * Allow anonymous users to download your code (not only by `git clone`). + * Allow anonymous users to register and report issues on public projects. -* powered by Ruby on Rails -* completely free and open source (MIT license) -* used by more than 25.000 organizations to keep their code secure +With these features, GitLab can be a self-hosted Github competitor. -### Code status +You can browse a live example at http://git.hoa.ro (you won't be able to create projects). -* [](http://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch) +_Disclaimer_: I do not provide any support on GitLab itself. I only contribute to the _public_ part. Please refer to the [official documentation](https://github.com/gitlabhq/gitlabhq/blob/master/README.md) for any help on GitLab itself. -* [](https://codeclimate.com/github/gitlabhq/gitlabhq) +You should also be aware that **Public GitLab** only applies to the latest [stable](https://github.com/ArthurHoaro/Public-GitLab/) release branch of GitLab. So, use the *-stable branches! The `master` branch on this repo has a high chance to be broken. +## Changelog -* [](https://gemnasium.com/gitlabhq/gitlabhq) this button can be yellow (small updates are available) but must not be red (a security fix or an important update is available), gems are updated in major releases of GitLab. + * [2013-10-05] : Public GitLab supports GitLab 6.1 (stable) - [Upgrade 6.0 to 6.1](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/6.0-to-6.1.md) + * [2013-08-25] : Public GitLab supports GitLab 6.0 (stable) - [Upgrade 5.4 to 6.0](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/5.4-to-6.0.md) + + > Note: Follow [@PGitLab](https://twitter.com/PGitLab) to get news on the project (or [RSS feed here](http://rssbridge.org/b/Twitter/Atom/u/pgitlab/)). -* [](https://coveralls.io/r/gitlabhq/gitlabhq) + * [2013-07-29] : Fixes 2 issues (more at #22) + * [2013-07-24] : Public GitLab supports GitLab 5.4 (stable) - [Upgrade 5.3 to 5.4](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/5.3-to-5.4.md) + * [2013-07-06] : [New feature](https://github.com/ArthurHoaro/Public-GitLab/pull/19) ! Added a different projects number limit per user for private and public projects. Thanks to [Mike](https://github.com/MJSmith5) for the idea. + + > Please update your DB model to use it ( `bundle exec rake db:migrate RAILS_ENV=production` ). + > Warning: New option in `config/gitlab.yml.example` (`default_projects_limit_private`). + + * [2013-06-30] : Public GitLab supports GitLab 5.3 (stable) - [Upgrade 5.2 to 5.3](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/5.2-to-5.3.md) + * [2013-05-29] : Public GitLab supports GitLab 5.2 (stable) - [Upgrade 5.1 to 5.2](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/5.1-to-5.2.md) + * [2013-05-03] : Bugfix (you need to [update](https://github.com/ArthurHoaro/Public-GitLab#update-public-gitlab) your DB triggers) + * [2013-04-25] : Public GitLab supports GitLab 5.1 (stable) - [Upgrade 5.0 to 5.1](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/5.0-to-5.1.md) -### Resources +> Warning: GitLab 5.1 does not work properly with old version of Git (ok on 1.7.10+). [More here](https://github.com/gitlabhq/gitlabhq/issues/3666). + + * [2013-04-11] : MySQL support + * [2013-04-01] : First commit for Public GitLab (only PostgreSQL) -* GitLab.org community site: [Homepage](http://gitlab.org) | [Screenshots](http://gitlab.org/screenshots/) | [Blog](http://blog.gitlab.org/) | [Demo](http://demo.gitlabhq.com/users/sign_in) +## Installation -* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) | [Subscription](http://www.gitlab.com/subscription/) | [Consultancy](http://www.gitlab.com/consultancy/) | [GitLab Cloud](http://www.gitlab.com/cloud/) | [Blog](http://blog.gitlab.com/) +During the [official installation](https://github.com/gitlabhq/gitlabhq/blob/6-1-stable/doc/install/installation.md) workflow, **Public GitLab** override part _"6. GitLab - Clone the Source"_. -* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server +**Warning**: Remember that you _need_ to use the latest **stable branch**, even if you want to download it from [zip file](https://github.com/ArthurHoaro/Public-GitLab/archive/6-1-stable.zip). -### Requirements +> Note: You can also use my [GitLab install scripts](http://git.hoa.ro/arthur/gitlab-install) for CentOS. -* Ubuntu/Debian** -* ruby 1.9.3+ -* git 1.7.10+ -* redis 2.0+ -* MySQL or PostgreSQL +### Clone the Source -** More details are in the [requirements doc](doc/install/requirements.md) + # Clone GitLab repository + sudo -u git -H git clone https://github.com/ArthurHoaro/Public-GitLab.git gitlab -### Installation + # Go to gitlab dir + cd /home/git/gitlab -#### Official production installation + # Checkout to stable release + sudo -u git -H git checkout 6-1-stable -* [Installation guide for a production server](doc/install/installation.md) +### Post installation +At this point, all of the GitLab components are installed. You still can't access GitLab though. +The SQL script below creates a default `guest` user for anonymous access. It also creates a default team (`pgl_reporters`), giving `reporter` permission to all _future_ users for all public projects. -#### Official development installation +> Note that your DB user needs to have the TRIGGER permission on your database (this is specific to Public GitLab). -If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working with all dependencies. +#### PostgreSQL +You have to patch your GitLab database with 2 SQL scripts: -* [Vagrant virtual machine for development](https://github.com/gitlabhq/gitlab-vagrant-vm) + cd /home/git/gitlab/pgl + psql -h host -U user database < pgl_pgsql_insert.sql + psql -h host -U user database < pgl_pgsql_trigger.sql +#### MySQL +You have to patch your GitLab database with 2 SQL scripts: -#### Unofficial production installations + cd /home/git/gitlab/pgl + mysql -hhost -uuser -p + use database + source pgl_mysql_insert.sql + source pgl_mysql_trigger.sql -* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes) repository with unofficial guides for using GitLab with different software (operating systems, webservers, etc.) than the official version. +### Allow signup -* [Installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) public wiki with unofficial guides to install GitLab on different operating systems. +In the file ~/gitlab/config/gitlab.yml, uncomment: -* [BitNami one-click installers](http://bitnami.com/stack/gitlab) + signup_enabled: true -* [TurnKey Linux virtual appliance](http://www.turnkeylinux.org/gitlab) +Note: Keep in mind that if you do not allow signups, guests won't be able to report issues. +If you do not want guest users to create projects on your GitLab installation, set `default_projects_limit: 0` in `config/gitlab.yaml`. -### New versions and upgrading +### Restart GitLab -Since 2011 GitLab is released on the 22nd of every month. Every new release includes an upgrade guide. +Remember to restart GitLab after all these changes : -* [Upgrade guides](doc/update) + sudo /etc/init.d/gitlab restart -* [Changelog](CHANGELOG) +Then enjoy ! -* Features that will be in the next releases are listed on [the feedback and suggestions forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457). +## Update Public GitLab +You need to refer to official [update guides](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/doc/update/) to upgrade GitLab version. -### Run in production mode +If the changelog on this README indicates any SQL update, you need to update your database : -The Installation guide contains instructions on how to download an init script and run it automatically on boot. You can also start the init script manually: +PostgreSQL: - sudo service gitlab start + cd /home/git/gitlab/pgl + psql -h host -U user database < pgl_pgsql_trigger.sql + -or by directly calling the script +MySQL: - sudo /etc/init.d/gitlab start + cd /home/git/gitlab/pgl + mysql -hhost -uuser -p + use database + source pgl_mysql_trigger.sql -### Run in development mode -Start it with [Foreman](https://github.com/ddollar/foreman) +## Reporting issues - bundle exec foreman start -p 3000 +See [CONTRIBUTING](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/CONTRIBUTING.md). -or start each component separately +If there is a new stable branch, please do not open an issue to ask for an update. [Contact me](http://hoa.ro/static6/contact) instead. - bundle exec rails s - bundle exec rake sidekiq:start +## Troubleshooting -### Run the tests +### Removing root user -* Seed the database +The reporters team created by Public GitLab is owned by the root user (Administrator). If you delete this user, it will cause problems in your GitLab installation. - bundle exec rake db:setup RAILS_ENV=test - bundle exec rake db:seed_fu RAILS_ENV=test +If you _really_ need to remove `root`, you need to change the `pgl_reporters` team's owner in GitLab administration before deleting it. -* Run all tests +If you have already deleted the root user, you have to manually change Public GitLab SQL `insert` to : - bundle exec rake gitlab:test + INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description) + VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'YOU_NEW_ADMIN_USERNAME'), now(), now(), 'Default new users team (reporter permission)'); -* [RSpec](http://rspec.info/) unit and functional tests +Read more at issues [#3](https://github.com/ArthurHoaro/Public-GitLab/issues/3) and [#4](https://github.com/ArthurHoaro/Public-GitLab/issues/4). - All RSpec tests: bundle exec rake spec +### Styles don't apply properly - Single RSpec file: bundle exec rspec spec/controllers/commit_controller_spec.rb +I had an issue with styles while upgrading from 5.4 to 6.0, so if it can help, here is what to do : -* [Spinach](https://github.com/codegram/spinach) integration tests + * Stop your Public-GitLab instance. + * Execute : - All Spinach tests: bundle exec rake spinach +``` +RAILS_ENV=production bundle exec rake assets:clean +RAILS_ENV=production bundle exec rake assets:precompile +``` - Single Spinach test: bundle exec spinach features/project/issues/milestones.feature + * Restart your Public-GitLab instance. +## License -### GitLab interfaces +Public GitLab is provided and maintained by [Arthur Hoaro](http://hoa.ro). -* [GitLab API](doc/api/README.md) +Public GitLab is distributed under the [same license](https://github.com/ArthurHoaro/Public-GitLab/blob/6-1-stable/LICENSE) as the original software. -* [Rake tasks](doc/raketasks) - -* [Directory structure](doc/install/structure.md) - -* [Databases](doc/install/databases.md) - - -### Getting help - -* [Maintenance policy](MAINTENANCE.md) specifies what versions are supported. - -* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems. - -* [Mailing list](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix. - -* [Unofficial #gitlab IRC on Freenode](http://www.freenode.net/) is another way to get in touch with other GitLab users who may be able to help you. - -* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab. - -* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed. - -* [Support subscription](http://www.gitlab.com/subscription/) connects you to the knowledge of GitLab experts that will resolve your issues and answer your questions. - -* [Consultancy](http://www.gitlab.com/consultancy/) allows you hire GitLab experts for installations, upgrades and customizations. - - -### Getting in touch - -* [Core team](https://github.com/gitlabhq?tab=members) - -* [Contributors](https://github.com/gitlabhq/gitlabhq/graphs/contributors) - -* [Leader](https://github.com/randx) - -* [Contact page](http://gitlab.org/contact/) +This fork is based on [cjdelisle](https://github.com/cjdelisle/) work, from his [original fork](https://github.com/cjdelisle/gitboria.com/commit/61db393bfd4fc75c5f046f01b01c7f114f601426). diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000000000000000000000000000000000000..879064dc719aeb7bf70f894c18a1f9eea680ada2 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,5 @@ +## GitLab Roadmap + +Features that will be in the next release are listed on [the feedback and suggestions forum with the status "started"](http://feedback.gitlab.com/forums/176466-general/status/796456) as specified in the README. + +This ROADMAP file will be deprecated. diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d974600dcc17c66789f1f9fa90f541fada30c39c..8c2f7a380bce5819b5dd070ad206d77ce4fb4794 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -21,8 +21,26 @@ class ApplicationController < ActionController::Base log_exception(exception) render "errors/not_found", layout: "errors", status: 404 end + + def current_user + super || guest_user + end + + def authenticate_user!(*args) + current_user.present? || super(*args) + end + + def reject_guest! + if current_user.is_guest? + redirect_to new_user_session_path + end + end protected + + def guest_user + User.find_by_username!('guest'); + end def log_exception(exception) application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index c36dae2abd31539ee42b5e15d9994f910e16f68f..bf1f5962d0acec41608c4d09de73ada440fbff48 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -1,6 +1,8 @@ class Profiles::KeysController < ApplicationController layout "profile" + before_filter :reject_guest! + def index @keys = current_user.keys.order('id DESC').all end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 6fa635d0e365a8999bb6800f6bd41f5d3f2c1af3..d489fd14ebd69e2643950ffd30f61124b9307b56 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -1,6 +1,7 @@ class ProfilesController < ApplicationController include ActionView::Helpers::SanitizeHelper + before_filter :reject_guest! before_filter :user before_filter :authorize_change_password!, only: :update_password before_filter :authorize_change_username!, only: :update_username diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 4947c33f959adf962e341086d425a8777af44e2e..9b934a34fd01351b53bd8c16b3ef7078777909b6 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -3,7 +3,7 @@ class UsersController < ApplicationController def show @user = User.find_by_username!(params[:username]) - @projects = @user.authorized_projects.where('projects.id in (?)', current_user.authorized_projects.map(&:id)) + @projects = @user.authorized_personal_projects.where('projects.id in (?)', current_user.authorized_projects.map(&:id)) @events = @user.recent_events.where(project_id: @projects.map(&:id)).limit(20) @title = @user.name diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 3a1cf59fd1ab92b908cfb75a091a9dfe9bbc6a36..011edb96c9f59f24104ac4e058dc6dc3068da42a 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -3,6 +3,10 @@ module ProjectsHelper "You are going to remove #{user.name} from #{project.name} project team. Are you sure?" end + def projects_labels + Project.tag_counts_on(:labels).map(&:name) + end + def link_to_project project link_to project do title = content_tag(:strong, project.name) diff --git a/app/models/ability.rb b/app/models/ability.rb index 8335829f91967a67db73c295286eba37e09976da..f060f6cd2a5b1650e4d210a57becf37639d27882 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -40,12 +40,15 @@ class Ability elsif team.guests.include?(user) rules << project_guest_rules - end - if project.public? - rules << public_project_rules + elsif project.is_public? + rules << project_anon_rules end + # if project.public? + # rules << public_project_rules + # end + if project.owner == user || user.admin? rules << project_admin_rules end @@ -74,7 +77,7 @@ class Ability ] end - def project_guest_rules + def project_anon_rules [ :read_project, :read_wiki, @@ -84,12 +87,18 @@ class Ability :read_team_member, :read_merge_request, :read_note, - :write_project, - :write_issue, + :download_code, + :write_issue, :write_note ] end + def project_guest_rules + project_anon_rules + [ + :write_project, + ] + end + def project_report_rules project_guest_rules + [ :download_code, @@ -165,14 +174,14 @@ class Ability [:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name| define_method "#{name}_abilities" do |user, subject| - if subject.author == user + if subject.author == user && subject.author.username != "guest" [ :"read_#{name}", :"write_#{name}", :"modify_#{name}", :"admin_#{name}" ] - elsif subject.respond_to?(:assignee) && subject.assignee == user + elsif subject.respond_to?(:assignee) && subject.assignee == user && subject.author.username != "guest" [ :"read_#{name}", :"write_#{name}", diff --git a/app/models/project.rb b/app/models/project.rb old mode 100644 new mode 100755 index 63cd3505ec4ccf43ba6af0bee06bdaf14183e1b8..b0569c9d084d582102fba3ca6f22b530c17f9e05 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -159,8 +159,14 @@ class Project < ActiveRecord::Base end def check_limit - unless creator.can_create_project? - errors[:limit_reached] << ("Your own projects limit is #{creator.projects_limit}! Please contact administrator to increase it") + if self.public + unless creator.can_create_project? + errors[:limit_reached] << ("Your own public projects limit is #{creator.projects_limit}! Please contact administrator to increase it") + end + else + unless creator.can_create_project_priv? + errors[:limit_reached] << ("Your own private projects limit is #{creator.projects_limit_priv}! Please contact administrator to increase it") + end end rescue errors[:base] << ("Can't check your ability to create project") @@ -190,6 +196,10 @@ class Project < ActiveRecord::Base self.id end + def is_public? + self.public + end + def issues_labels @issues_labels ||= (issues_default_labels + issues.tags_on(:labels)).uniq.sort_by(&:name) end diff --git a/app/models/repository.rb b/app/models/repository.rb old mode 100644 new mode 100755 diff --git a/app/models/user.rb b/app/models/user.rb old mode 100644 new mode 100755 index c1026a44f872b7ccdb971696fe64e2d380c951ef..458830578c2d3d48fdbbbe42441c7417f78b9d07 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,6 +18,7 @@ # name :string(255) # admin :boolean default(FALSE), not null # projects_limit :integer default(10) +# projects_limit_priv :integer default(10) # skype :string(255) default(""), not null # linkedin :string(255) default(""), not null # twitter :string(255) default(""), not null @@ -47,7 +48,7 @@ class User < ActiveRecord::Base :extern_uid, :provider, :password_expires_at, as: [:default, :admin] - attr_accessible :projects_limit, :can_create_group, + attr_accessible :projects_limit, :projects_limit_priv, :can_create_group, as: :admin attr_accessor :force_random_password @@ -94,8 +95,10 @@ class User < ActiveRecord::Base has_many :personal_projects, through: :namespace, source: :projects has_many :projects, through: :users_projects has_many :own_projects, foreign_key: :creator_id, class_name: 'Project' - has_many :owned_projects, through: :namespaces, source: :projects - + has_many :owned_projects, through: :namespaces, source: :projects, + conditions: { projects: { public: true } } + has_many :owned_projects_priv, through: :namespaces, source: :projects, + conditions: { projects: { public: false } } # # Validations # @@ -104,6 +107,7 @@ class User < ActiveRecord::Base validates :bio, length: { within: 0..255 } validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} + validates :projects_limit_priv, presence: true, numericality: {greater_than_or_equal_to: 0} validates :username, presence: true, uniqueness: true, exclusion: { in: Gitlab::Blacklist.path }, format: { with: Gitlab::Regex.username_regex, @@ -210,6 +214,7 @@ class User < ActiveRecord::Base def defaults { projects_limit: Gitlab.config.gitlab.default_projects_limit, + projects_limit_priv: Gitlab.config.gitlab.default_projects_limit_private, can_create_group: Gitlab.config.gitlab.default_can_create_group, theme_id: Gitlab::Theme::MARS } @@ -253,10 +258,21 @@ class User < ActiveRecord::Base # Projects user has access to def authorized_projects @authorized_projects ||= begin - project_ids = (owned_projects.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id)).uniq + project_ids = (owned_projects.pluck(:id) + owned_projects_priv.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id) + public_projects.pluck(:id)) .uniq Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC') end end + + def authorized_personal_projects + @authorized_personal_projects ||= begin + project_ids = (owned_projects.pluck(:id) + groups_projects.pluck(:id) + owned_projects_priv.pluck(:id) + users_projects.where("project_access > 20").pluck(:project_id)).uniq + Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC') + end + end + + def public_projects + Project.where("projects.public = true") + end # Team membership in authorized projects def tm_in_authorized_projects @@ -267,18 +283,26 @@ class User < ActiveRecord::Base admin end + def is_guest? + username == 'guest' + end + def require_ssh_key? - keys.count == 0 + !is_guest? && keys.count == 0 end def can_change_username? - Gitlab.config.gitlab.username_changing_enabled + !is_guest? && Gitlab.config.gitlab.username_changing_enabled end def can_create_project? projects_limit_left > 0 end + def can_create_project_priv? + projects_limit_priv > owned_projects_priv.count + end + def can_create_group? can?(:create_group, nil) end @@ -316,6 +340,15 @@ class User < ActiveRecord::Base (personal_projects.count.to_f / projects_limit) * 100 end + def projects_limit_left_priv + projects_limit_priv - owned_projects_priv.count + end + + def projects_limit_percent_priv + return 100 if projects_limit_priv.zero? + (owned_projects_priv.count.to_f / projects_limit_priv) * 100 + end + def recent_push project_id = nil # Get push events not earlier than 2 hours ago events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours) diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml old mode 100644 new mode 100755 diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 3f930c45fa61647a7db27d9e3fd718cf9cf3054b..1b53598994f68a3562b126bd8a1e43c37332bcb0 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -48,11 +48,15 @@ %legend Access .row .span8 - .control-group - = f.label :projects_limit - .controls= f.number_field :projects_limit + .clearfix + = f.label :projects_limit_public + .input= f.number_field :projects_limit - .control-group + .clearfix + = f.label :projects_limit_private + .input= f.number_field :projects_limit_priv + + .clearfix = f.label :can_create_group .controls= f.check_box :can_create_group diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml old mode 100644 new mode 100755 index 6492c122ba04c97505a426b719a5bf0ec357d349..d911bdff7746efa0563b7597238480967b7396da --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -1,40 +1,51 @@ -%header.navbar.navbar-static-top.navbar-gitlab - .navbar-inner - .container - %div.app_logo - %span.separator - = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do - %h1 GITLAB - %span.separator - %h1.project_name= title - %ul.nav - %li - %a - %div.hide.turbolink-spinner - %i.icon-refresh.icon-spin - Loading... - %li - = render "layouts/search" - %li - = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do - %i.icon-globe - %li - = link_to user_snippets_path(current_user), title: "My snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do - %i.icon-paste - - if current_user.is_admin? - %li - = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do - %i.icon-cogs - - if current_user.can_create_project? - %li - = link_to new_project_path, title: "New project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do - %i.icon-plus - %li - = link_to profile_path, title: "My profile", class: 'has_bottom_tooltip', 'data-original-title' => 'My profile' do - %i.icon-user - %li - = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do - %i.icon-signout - %li - = link_to current_user, class: "profile-pic", id: 'profile-pic' do - = image_tag gravatar_icon(current_user.email, 26), alt: '' +%header.navbar.navbar-static-top.navbar-gitlab + .navbar-inner + .container + %div.app_logo + %span.separator + = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do + %h1 GITLAB + %span.separator + %h1.project_name= title + %ul.nav + %li + %a + %div.hide.turbolink-spinner + %i.icon-refresh.icon-spin + Loading... + %li + = render "layouts/search" + %li + = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do + %i.icon-globe + - unless current_user.is_guest? + %li + = link_to user_snippets_path(current_user), title: "My snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do + %i.icon-paste + - if current_user.is_admin? + %li + = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do + %i.icon-cogs + - if current_user.can_create_project? || current_user.can_create_project_priv? + %li + = link_to new_project_path, title: "Create New Project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do + %i.icon-plus + %li.separator + %li + - if current_user.is_guest? + = link_to profile_path, title: "Login", class: 'has_bottom_tooltip', 'data-original-title' => 'Login' do + %i.icon-user + - if Gitlab.config.gitlab.signup_enabled + %li + = link_to "#{user_registration_path}/sign_up", title: "Signup", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign Up' do + %i.icon-briefcase + - else + %li + = link_to profile_path, title: "My profile", class: 'has_bottom_tooltip', 'data-original-title' => 'My profile' do + %i.icon-user + %li + = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do + %i.icon-signout + %li + = link_to current_user, class: "profile-pic" do + = image_tag(gravatar_icon(current_user.email, 26), alt: '') \ No newline at end of file diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 25bf7912f1eb8d1f4e2ffd1013ecd588a4a29361..0478aa6e46f5380f93a37220b4b0d355bfccce55 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -69,7 +69,7 @@ - unless current_user.projects_limit_left > 100 %fieldset %legend - Personal projects: + Owned public projects: %small.pull-right %span= current_user.personal_projects.count of @@ -78,6 +78,18 @@ .progress .bar{style: "width: #{current_user.projects_limit_percent}%;"} + - unless current_user.projects_limit_left_priv > 100 + %fieldset + %legend + Owned private projects: + %small.pull-right + %span= current_user.owned_projects_priv.count + of + %span= current_user.projects_limit_priv + .padded + .progress + .bar{style: "width: #{current_user.projects_limit_percent_priv}%;"} + %fieldset %legend SSH public keys: diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml old mode 100644 new mode 100755 diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml old mode 100644 new mode 100755 diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml old mode 100644 new mode 100755 index 539c45edd947b11bf48cc90f8a5101f9fd8a32dc..98a29b362b5da1bc4c57815ef4d0872921b49fb1 --- a/app/views/projects/issues/_issues.html.haml +++ b/app/views/projects/issues/_issues.html.haml @@ -11,6 +11,7 @@ = hidden_field_tag 'update[issues_ids]', [] = hidden_field_tag :status, params[:status] = button_tag "Save", class: "btn update_selected_issues btn-small btn-save" + .issues-filters %span Filter by .dropdown.inline.prepend-left-10 diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml old mode 100644 new mode 100755 index 81594b4972e3161d2d0b655f9ec8c994f2f322b3..ea8ccca4c9c32d9251cae0c438c5e573c3f7cafc --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -9,6 +9,7 @@ = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-right", title: "New Issue", id: "new_issue_link" do %i.icon-plus New Issue + = form_tag project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: 'pull-right' do = hidden_field_tag :status, params[:status], id: 'search_status' = hidden_field_tag :assignee_id, params[:assignee_id], id: 'search_assignee_id' diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml old mode 100644 new mode 100755 index 0213576927bc5710bb66b835cb8d8ff084a48442..76f76ea14398179eb403c0808d31a396d57a4f4c --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -54,6 +54,15 @@ = f.check_box :public, { checked: Gitlab.config.gitlab.default_projects_features.public }, true, false %span.help-inline Make project visible to everyone + + %p.padded + .clearfix + = f.label :public do + Make this project visible to the public + .input + = f.check_box :public, { :checked => 'checked' }, true, nil + %hr + .form-actions = f.submit 'Create project', class: "btn btn-create project-submit", tabindex: 4 diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index fbc924c4e1de96233e85856a31f536321acb97bf..a7df6284fa20e3c1626561c810a2c35438c1f80b 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -5,7 +5,7 @@ %i.icon-link Link here - - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) + - if(note.author_id == current_user.id && current_user.username != "guest") || can?(current_user, :admin_note, @project) = link_to "#", title: "Edit comment", class: "js-note-edit" do %i.icon-edit Edit diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 0434601cb4982ce567443397a913bd138b1a4b61..8c768abfdc4864c0f5c8185f7074d46b5221f708 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -40,6 +40,7 @@ production: &base ## User settings default_projects_limit: 10 + default_projects_limit_private: 5 # default_can_create_group: false # default: true # username_changing_enabled: false # default: true - User can change her username/namespace diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index da7a83a62a4a1ba0c86111db1b748b40b32be898..73d2a67228eb988f2a64488d71ce51c0aab3b108 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -51,6 +51,7 @@ Settings['issues_tracker'] ||= {} # Settings['gitlab'] ||= Settingslogic.new({}) Settings.gitlab['default_projects_limit'] ||= 10 +Settings.gitlab['default_projects_limit_private'] ||= 5 Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil? Settings.gitlab['host'] ||= 'localhost' Settings.gitlab['https'] = false if Settings.gitlab['https'].nil? diff --git a/db/migrate/20130630204200_add_private_limit.rb b/db/migrate/20130630204200_add_private_limit.rb new file mode 100644 index 0000000000000000000000000000000000000000..639798b9ab77d38be834ce2bde98e30e2b3ce40b --- /dev/null +++ b/db/migrate/20130630204200_add_private_limit.rb @@ -0,0 +1,5 @@ +class AddPrivateLimit < ActiveRecord::Migration + def change + add_column :users, :projects_limit_priv, :integer, default: 5, null: true + end +end diff --git a/db/migrate/20130821090530_remove_deprecated_tables.rb b/db/migrate/20130821090530_remove_deprecated_tables.rb deleted file mode 100644 index 539c0617eeb7747e851da95d6ba6b5b96934c73f..0000000000000000000000000000000000000000 --- a/db/migrate/20130821090530_remove_deprecated_tables.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RemoveDeprecatedTables < ActiveRecord::Migration - def up - drop_table :user_teams - drop_table :user_team_project_relationships - drop_table :user_team_user_relationships - end - - def down - raise 'No rollback for this migration' - end -end diff --git a/db/schema.rb b/db/schema.rb index d5effe40ea1f0e9ec0663fbc2fc1797a2563e30d..858910081a7d7313472fe23768cdbf7b933d6d6f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -55,8 +55,8 @@ ActiveRecord::Schema.define(:version => 20130909132950) do t.integer "assignee_id" t.integer "author_id" t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.integer "position", :default => 0 t.string "branch_name" t.text "description" @@ -168,8 +168,8 @@ ActiveRecord::Schema.define(:version => 20130909132950) do t.string "name" t.string "path" t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.integer "creator_id" t.string "default_branch" t.boolean "issues_enabled", :default => true, :null => false @@ -242,53 +242,50 @@ ActiveRecord::Schema.define(:version => 20130909132950) do t.datetime "created_at" end - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" - add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" - create_table "tags", :force => true do |t| t.string "name" end create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + t.integer "sign_in_count", :default => 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "name" - t.boolean "admin", :default => false, :null => false - t.integer "projects_limit", :default => 10 - t.string "skype", :default => "", :null => false - t.string "linkedin", :default => "", :null => false - t.string "twitter", :default => "", :null => false + t.boolean "admin", :default => false, :null => false + t.integer "projects_limit", :default => 10 + t.string "skype", :default => "", :null => false + t.string "linkedin", :default => "", :null => false + t.string "twitter", :default => "", :null => false t.string "authentication_token" - t.integer "theme_id", :default => 1, :null => false + t.integer "theme_id", :default => 1, :null => false t.string "bio" - t.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", :default => 0 t.datetime "locked_at" t.string "extern_uid" t.string "provider" t.string "username" - t.boolean "can_create_group", :default => true, :null => false - t.boolean "can_create_team", :default => true, :null => false + t.boolean "can_create_group", :default => true, :null => false + t.boolean "can_create_team", :default => true, :null => false t.string "state" - t.integer "color_scheme_id", :default => 1, :null => false - t.integer "notification_level", :default => 1, :null => false + t.integer "color_scheme_id", :default => 1, :null => false + t.integer "notification_level", :default => 1, :null => false t.datetime "password_expires_at" t.integer "created_by_id" + t.integer "projects_limit_priv", :default => 5 end add_index "users", ["admin"], :name => "index_users_on_admin" add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token", :unique => true add_index "users", ["email"], :name => "index_users_on_email", :unique => true - add_index "users", ["extern_uid", "provider"], :name => "index_users_on_extern_uid_and_provider", :unique => true add_index "users", ["name"], :name => "index_users_on_name" add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true add_index "users", ["username"], :name => "index_users_on_username" @@ -307,8 +304,8 @@ ActiveRecord::Schema.define(:version => 20130909132950) do create_table "users_projects", :force => true do |t| t.integer "user_id", :null => false t.integer "project_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.integer "project_access", :default => 0, :null => false t.integer "notification_level", :default => 3, :null => false end @@ -320,8 +317,8 @@ ActiveRecord::Schema.define(:version => 20130909132950) do create_table "web_hooks", :force => true do |t| t.string "url" t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "type", :default => "ProjectHook" t.integer "service_id" end diff --git a/doc/install/installation.md b/doc/install/installation.md index 660d7fa2bc1817670412b97c8a0677c0f53778b7..dab655d942264f5b46188b8612ae8faba4852624 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -379,7 +379,6 @@ These steps are fairly general and you will need to figure out the exact details * Start GitLab `sudo service gitlab start` - ### Examples If you have successfully set up a provider that is not shipped with GitLab itself, please let us know. diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 3e929c52990de1633104b0448a5cee5e189efb3a..54bf6fb905927b8fa191edf201a86ea4936f6679 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -1,6 +1,6 @@ # GITLAB # Maintainer: @randx -# App Version: 5.0 +# App Version: 6.1 upstream gitlab { server unix:/home/git/gitlab/tmp/sockets/gitlab.socket; diff --git a/pgl/pgl_mysql_insert.sql b/pgl/pgl_mysql_insert.sql new file mode 100755 index 0000000000000000000000000000000000000000..f47d6c254841a7863005b839798485a51597e7e7 --- /dev/null +++ b/pgl/pgl_mysql_insert.sql @@ -0,0 +1,5 @@ +INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) +VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f'); + +INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description) +VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)'); \ No newline at end of file diff --git a/pgl/pgl_mysql_trigger.sql b/pgl/pgl_mysql_trigger.sql new file mode 100755 index 0000000000000000000000000000000000000000..ec23fbfd6f50c0afca56ecafb5e4e7a952170ea8 --- /dev/null +++ b/pgl/pgl_mysql_trigger.sql @@ -0,0 +1,112 @@ +DROP TRIGGER IF EXISTS pgl_new_user; +DROP TRIGGER IF EXISTS pgl_new_project; +DROP TRIGGER IF EXISTS pgl_update_project; + +delimiter // + +CREATE TRIGGER pgl_new_user +AFTER INSERT ON users FOR EACH ROW +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE m_projects_id integer; + DECLARE cur CURSOR FOR SELECT project_id FROM user_team_project_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters"); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN cur; + ins_loop: LOOP + FETCH cur INTO m_projects_id; + IF done THEN + LEAVE ins_loop; + END IF; + + INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) + VALUES (NEW.id, m_projects_id, now(), now(), 20); + END LOOP; + CLOSE cur; + + INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now()); +END// + +DELIMITER ; +delimiter // + +CREATE TRIGGER pgl_new_project +AFTER INSERT ON projects FOR EACH ROW +BEGIN + DECLARE m_users_id integer; + DECLARE done INT DEFAULT FALSE; + + DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters"); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + IF NEW.public = 1 THEN + OPEN cur; + ins_loop: LOOP + FETCH cur INTO m_users_id; + IF done THEN + LEAVE ins_loop; + END IF; + + IF m_users_id <> NEW.creator_id THEN + INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) + VALUES (m_users_id, NEW.id, now(), now(), 20); + END IF; + END LOOP; + CLOSE cur; + + INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now()); + END IF; +END// + +DELIMITER ; +delimiter // + +CREATE TRIGGER pgl_update_project +AFTER UPDATE ON projects FOR EACH ROW +BEGIN + DECLARE m_users_id integer; + DECLARE done INT DEFAULT FALSE; + DECLARE rows INT; + DECLARE cur CURSOR FOR SELECT user_id FROM user_team_user_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters"); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + IF NEW.public <> OLD.public THEN + if NEW.public = 1 THEN + + OPEN cur; + ins_loop: LOOP + FETCH cur INTO m_users_id; + IF done THEN + LEAVE ins_loop; + END IF; + + IF m_users_id <> NEW.creator_id THEN + SELECT count(*) INTO rows FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id; + IF rows = 0 THEN + INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) + VALUES (m_users_id, NEW.id, now(), now(), 20); + END IF; + END IF; + END LOOP; + CLOSE cur; + INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, (SELECT id FROM user_teams WHERE name = "pgl_reporters"), 20, now(), now()); + ELSE + OPEN cur; + ins_loop: LOOP + FETCH cur INTO m_users_id; + IF done THEN + LEAVE ins_loop; + END IF; + + SELECT project_access INTO rows FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id LIMIT 1; + -- If project permission is reporter (20), or lower + IF rows < 21 THEN + DELETE FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id; + END IF; + END LOOP; + CLOSE cur; + DELETE FROM user_team_project_relationships WHERE user_team_id = (SELECT id FROM user_teams WHERE name = "pgl_reporters") AND project_id = OLD.id; + END IF; + END IF; +END// +DELIMITER ; \ No newline at end of file diff --git a/pgl/pgl_pgsql_insert.sql b/pgl/pgl_pgsql_insert.sql new file mode 100755 index 0000000000000000000000000000000000000000..bd72b86b867620ed59a1097fcd5fa1ff75a09276 --- /dev/null +++ b/pgl/pgl_pgsql_insert.sql @@ -0,0 +1,5 @@ +INSERT INTO users (email, encrypted_password, name, username, projects_limit, can_create_team, can_create_group, sign_in_count, created_at, updated_at, admin ) +VALUES ('guest@local.host', '$2a$10$ivc.WwouK4tKT3ZtV8kiD.oVZRzJLV0df7K4nJRV73hhf9a92JeJ.', 'guest', 'guest', 0, 'f', 'f', 0, now(), now(), 'f'); + +INSERT INTO user_teams (name, path, owner_id, created_at, updated_at, description) +VALUES ('pgl_reporters', 'pgl_reporters', (SELECT id FROM users WHERE username = 'root'), now(), now(), 'Default new users team (reporter permission)'); diff --git a/pgl/pgl_pgsql_trigger.sql b/pgl/pgl_pgsql_trigger.sql new file mode 100755 index 0000000000000000000000000000000000000000..eba4a56e0329c3d6c0aabbdd89ed0d912012163a --- /dev/null +++ b/pgl/pgl_pgsql_trigger.sql @@ -0,0 +1,99 @@ +DROP TRIGGER IF EXISTS pgl_new_user ON users; +DROP TRIGGER IF EXISTS pgl_new_project ON projects; +DROP TRIGGER IF EXISTS pgl_update_project ON projects; + +CREATE OR REPLACE FUNCTION pgl_create_user_team_rs() RETURNS trigger +LANGUAGE plpgsql +AS $$ + DECLARE m_user_team_id integer; + DECLARE m_projects_id integer; + BEGIN + m_user_team_id := 0; + SELECT "id" INTO m_user_team_id + FROM "user_teams" p + WHERE p.name = 'pgl_reporters' + LIMIT 1; + + FOR m_projects_id IN SELECT project_id FROM user_team_project_relationships WHERE user_team_id = m_user_team_id LOOP + INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) + VALUES (NEW.id, m_projects_id, now(), now(), 20); + END LOOP; + + INSERT INTO user_team_user_relationships (user_id, user_team_id, permission, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now()); + RETURN new; + END; +$$; +CREATE TRIGGER pgl_new_user AFTER INSERT ON users FOR EACH ROW EXECUTE PROCEDURE pgl_create_user_team_rs(); + +CREATE OR REPLACE FUNCTION pgl_create_project_team_rs() RETURNS trigger +LANGUAGE plpgsql +AS $$ + DECLARE m_user_team_id integer; + DECLARE m_users_id integer; + BEGIN + IF NEW.public = 't' THEN + m_user_team_id := 0; + SELECT "id" INTO m_user_team_id + FROM "user_teams" p + WHERE p.name = 'pgl_reporters' + LIMIT 1; + + FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id LOOP + IF m_users_id <> NEW.creator_id THEN + INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) + VALUES (m_users_id, NEW.id, now(), now(), 20); + END IF; + END LOOP; + + INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (NEW.id, m_user_team_id, 20, now(), now()); + END IF; + RETURN new; + END; +$$; +CREATE TRIGGER pgl_new_project AFTER INSERT ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_create_project_team_rs(); + +CREATE OR REPLACE FUNCTION pgl_update_project_team_rs() RETURNS trigger +LANGUAGE plpgsql +AS $$ + DECLARE + m_user_team_id integer; + m_users_id integer; + temprec RECORD; + tmpint INTEGER := 0; + BEGIN + IF NEW.public <> OLD.public THEN + m_user_team_id := 0; + SELECT "id" INTO m_user_team_id + FROM "user_teams" p + WHERE p.name = 'pgl_reporters' + LIMIT 1; + + IF NEW.public = 't' THEN + FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id LOOP + IF m_users_id <> OLD.creator_id THEN + SELECT user_id FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id INTO temprec; + GET DIAGNOSTICS tmpint = ROW_COUNT; + IF tmpint = 0 THEN + INSERT INTO users_projects (user_id, project_id, created_at, updated_at, project_access) + VALUES (m_users_id, OLD.id, now(), now(), 20); + END IF; + END IF; + END LOOP; + + INSERT INTO user_team_project_relationships (project_id, user_team_id, greatest_access, created_at, updated_at) VALUES (OLD.id, m_user_team_id, 20, now(), now()); + + ELSE + FOR m_users_id IN SELECT user_id FROM user_team_user_relationships WHERE user_team_id = m_user_team_id LOOP + SELECT project_access INTO tmpint FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id LIMIT 1; + -- If project permission is reporter (20), or lower + IF tmpint < 21 THEN + DELETE FROM users_projects WHERE user_id = m_users_id AND project_id = OLD.id; + END IF; + END LOOP; + DELETE FROM user_team_project_relationships WHERE user_team_id = m_user_team_id AND project_id = OLD.id; + END IF; + END IF; + RETURN new; + END; +$$; +CREATE TRIGGER pgl_update_project AFTER UPDATE ON projects FOR EACH ROW EXECUTE PROCEDURE pgl_update_project_team_rs(); \ No newline at end of file diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..bf2cd98eba14fac175a1301c4e6924ed8bbfd03e --- /dev/null +++ b/spec/lib/gitlab/git/commit_spec.rb @@ -0,0 +1,40 @@ +require "spec_helper" + +describe Gitlab::Git::Commit do + let(:commit) { create(:project_with_code).repository.commit } + + describe "Commit info" do + before do + @committer = double( + email: 'mike@smith.com', + name: 'Mike Smith' + ) + + @author = double( + email: 'john@smith.com', + name: 'John Smith' + ) + + @raw_commit = double( + id: "bcf03b5de6abcf03b5de6c", + author: @author, + committer: @committer, + committed_date: Date.yesterday, + authored_date: Date.yesterday, + parents: [], + message: 'Refactoring specs' + ) + + @commit = Gitlab::Git::Commit.new(@raw_commit) + end + + it { @commit.short_id.should == "bcf03b5de6a" } + it { @commit.safe_message.should == @raw_commit.message } + it { @commit.created_at.should == @raw_commit.committed_date } + it { @commit.author_email.should == @author.email } + it { @commit.author_name.should == @author.name } + it { @commit.committer_name.should == @committer.name } + it { @commit.committer_email.should == @committer.email } + it { @commit.different_committer?.should be_true } + end +end diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..5191b1190a69c208ce26a6a7a6b987bd64ba89b3 --- /dev/null +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -0,0 +1,34 @@ +require "spec_helper" + +describe Gitlab::Git::Diff do + before do + @raw_diff_hash = { + diff: 'Hello world', + new_path: 'temp.rb', + old_path: 'test.rb', + a_mode: '100644', + b_mode: '100644', + new_file: false, + renamed_file: true, + deleted_file: false, + } + + @grit_diff = double('Grit::Diff', @raw_diff_hash) + end + + context 'init from grit' do + before do + @diff = Gitlab::Git::Diff.new(@raw_diff_hash) + end + + it { @diff.to_hash.should == @raw_diff_hash } + end + + context 'init from hash' do + before do + @diff = Gitlab::Git::Diff.new(@grit_diff) + end + + it { @diff.to_hash.should == @raw_diff_hash } + end +end diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..2b0550aa72a163d666a405f1701911c45d6233d8 --- /dev/null +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -0,0 +1,123 @@ +require "spec_helper" + +describe Gitlab::Git::Repository do + let(:repository) { Gitlab::Git::Repository.new('gitlabhq', 'master') } + + describe "Respond to" do + subject { repository } + + it { should respond_to(:repo) } + it { should respond_to(:tree) } + it { should respond_to(:root_ref) } + it { should respond_to(:tags) } + it { should respond_to(:commit) } + it { should respond_to(:commits) } + it { should respond_to(:commits_between) } + it { should respond_to(:commits_with_refs) } + end + + + describe "#discover_default_branch" do + let(:master) { 'master' } + let(:stable) { 'stable' } + + it "returns 'master' when master exists" do + repository.should_receive(:branch_names).at_least(:once).and_return([stable, master]) + repository.discover_default_branch.should == 'master' + end + + it "returns non-master when master exists but default branch is set to something else" do + repository.root_ref = 'stable' + repository.should_receive(:branch_names).at_least(:once).and_return([stable, master]) + repository.discover_default_branch.should == 'stable' + end + + it "returns a non-master branch when only one exists" do + repository.should_receive(:branch_names).at_least(:once).and_return([stable]) + repository.discover_default_branch.should == 'stable' + end + + it "returns nil when no branch exists" do + repository.should_receive(:branch_names).at_least(:once).and_return([]) + repository.discover_default_branch.should be_nil + end + end + + describe :commit do + it "should return first head commit if without params" do + repository.commit.id.should == repository.repo.commits.first.id + end + + it "should return valid commit" do + repository.commit(ValidCommit::ID).should be_valid_commit + end + + it "should return nil" do + repository.commit("+123_4532530XYZ").should be_nil + end + end + + describe :tree do + before do + @commit = repository.commit(ValidCommit::ID) + end + + it "should raise error w/o arguments" do + lambda { repository.tree }.should raise_error + end + + it "should return root tree for commit" do + tree = repository.tree(@commit) + tree.contents.size.should == ValidCommit::FILES_COUNT + tree.contents.map(&:name).should == ValidCommit::FILES + end + + it "should return root tree for commit with correct path" do + tree = repository.tree(@commit, ValidCommit::C_FILE_PATH) + tree.contents.map(&:name).should == ValidCommit::C_FILES + end + + it "should return root tree for commit with incorrect path" do + repository.tree(@commit, "invalid_path").should be_nil + end + end + + describe "commits" do + subject do + commits = repository.commits('master', 'app', 3, 1) + commits.map { |c| c.id } + end + + it { should have(3).elements } + it { should include("8716fc78f3c65bbf7bcf7b574febd583bc5d2812") } + it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") } + end + + describe "commits_between" do + subject do + commits = repository.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff", + "8470d70da67355c9c009e4401746b1d5410af2e3") + commits.map { |c| c.id } + end + + it { should have(3).elements } + it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") } + it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") } + end + + describe "branch names" do + subject { repository.branch_names } + + it { should have(32).elements } + it { should include("master") } + it { should_not include("branch-from-space") } + end + + describe "tag names" do + subject { repository.tag_names } + + it { should have(16).elements } + it { should include("v1.2.0") } + it { should_not include("v5.0.0") } + end +end diff --git a/spec/lib/gitlab/git/stats_spec.rb b/spec/lib/gitlab/git/stats_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..96b04f17e9186e882206f2c558b20a9d51b4e88f --- /dev/null +++ b/spec/lib/gitlab/git/stats_spec.rb @@ -0,0 +1,28 @@ +require "spec_helper" + +describe Gitlab::Git::Stats do + let(:repository) { Gitlab::Git::Repository.new('gitlabhq', 'master') } + + before do + @stats = Gitlab::Git::Stats.new(repository.raw, 'master') + end + + describe :authors do + let(:author) { @stats.authors.first } + + it { author.name.should == 'Dmitriy Zaporozhets' } + it { author.email.should == 'dmitriy.zaporozhets@gmail.com' } + it { author.commits.should == 254 } + end + + describe :graph do + let(:graph) { @stats.graph } + + it { graph.labels.should include Date.today.stamp('Aug 23') } + it { graph.commits.should be_kind_of(Array) } + it { graph.weeks.should == 4 } + end + + it { @stats.commits_count.should == 918 } + it { @stats.files_count.should == 550 } +end