Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
711f859532
commit
d7ed3b4766
38 changed files with 453 additions and 164 deletions
|
@ -604,7 +604,7 @@ GEM
|
|||
ruby_dep (~> 1.2)
|
||||
locale (2.1.2)
|
||||
lockbox (0.3.3)
|
||||
lograge (0.10.0)
|
||||
lograge (0.11.2)
|
||||
actionpack (>= 4)
|
||||
activesupport (>= 4)
|
||||
railties (>= 4)
|
||||
|
|
|
@ -54,7 +54,7 @@ export default Vue.extend({
|
|||
return this.issue.milestone ? this.issue.milestone.title : __('No milestone');
|
||||
},
|
||||
canRemove() {
|
||||
return !this.list.preset;
|
||||
return !this.list?.preset;
|
||||
},
|
||||
hasLabels() {
|
||||
return this.issue.labels && this.issue.labels.length;
|
||||
|
|
|
@ -2,5 +2,16 @@
|
|||
|
||||
module ApplicationCable
|
||||
class Channel < ActionCable::Channel::Base
|
||||
include Logging
|
||||
|
||||
private
|
||||
|
||||
def notification_payload(_)
|
||||
super.merge!(params: params.except(:channel))
|
||||
end
|
||||
|
||||
def request
|
||||
connection.request
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
|
||||
module ApplicationCable
|
||||
class Connection < ActionCable::Connection::Base
|
||||
include Logging
|
||||
|
||||
identified_by :current_user
|
||||
|
||||
public :request
|
||||
|
||||
def connect
|
||||
self.current_user = find_user_from_session_store
|
||||
end
|
||||
|
@ -18,5 +22,9 @@ module ApplicationCable
|
|||
def session_id
|
||||
Rack::Session::SessionId.new(cookies[Gitlab::Application.config.session_options[:key]])
|
||||
end
|
||||
|
||||
def notification_payload(_)
|
||||
super.merge!(params: request.params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
17
app/channels/application_cable/logging.rb
Normal file
17
app/channels/application_cable/logging.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ApplicationCable
|
||||
module Logging
|
||||
private
|
||||
|
||||
def notification_payload(_)
|
||||
super.merge!(
|
||||
Labkit::Correlation::CorrelationId::LOG_KEY => request.request_id,
|
||||
user_id: current_user&.id,
|
||||
username: current_user&.username,
|
||||
remote_ip: request.remote_ip,
|
||||
ua: request.env['HTTP_USER_AGENT']
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,6 +26,6 @@ module KnownSignIn
|
|||
end
|
||||
|
||||
def notify_user
|
||||
current_user.notification_service.unknown_sign_in(current_user, request.remote_ip)
|
||||
current_user.notification_service.unknown_sign_in(current_user, request.remote_ip, current_user.current_sign_in_at)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,13 +45,20 @@ module Emails
|
|||
end
|
||||
end
|
||||
|
||||
def unknown_sign_in_email(user, ip)
|
||||
def unknown_sign_in_email(user, ip, time)
|
||||
@user = user
|
||||
@ip = ip
|
||||
@time = time
|
||||
@target_url = edit_profile_password_url
|
||||
|
||||
Gitlab::I18n.with_locale(@user.preferred_language) do
|
||||
mail(to: @user.notification_email, subject: subject(_("Unknown sign-in from new location")))
|
||||
mail(
|
||||
to: @user.notification_email,
|
||||
subject: subject(_("%{host} sign-in from new location") % { host: Gitlab.config.gitlab.host })
|
||||
) do |format|
|
||||
format.html { render layout: 'mailer' }
|
||||
format.text { render layout: 'mailer' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -162,7 +162,7 @@ class NotifyPreview < ActionMailer::Preview
|
|||
end
|
||||
|
||||
def unknown_sign_in_email
|
||||
Notify.unknown_sign_in_email(user, '127.0.0.1').message
|
||||
Notify.unknown_sign_in_email(user, '127.0.0.1', Time.current).message
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -36,7 +36,7 @@ class ActiveSession
|
|||
timestamp = Time.current
|
||||
|
||||
active_user_session = new(
|
||||
ip_address: request.ip,
|
||||
ip_address: request.remote_ip,
|
||||
browser: client.name,
|
||||
os: client.os_name,
|
||||
device_name: client.device_name,
|
||||
|
|
|
@ -40,9 +40,13 @@ module Issuable
|
|||
private
|
||||
|
||||
def permitted_attrs(type)
|
||||
attrs = %i(state_event milestone_id assignee_id assignee_ids add_label_ids remove_label_ids subscription_event)
|
||||
attrs = %i(state_event milestone_id add_label_ids remove_label_ids subscription_event)
|
||||
|
||||
if type == 'issue'
|
||||
issuable_specific_attrs(type, attrs)
|
||||
end
|
||||
|
||||
def issuable_specific_attrs(type, attrs)
|
||||
if type == 'issue' || type == 'merge_request'
|
||||
attrs.push(:assignee_ids)
|
||||
else
|
||||
attrs.push(:assignee_id)
|
||||
|
|
|
@ -68,10 +68,10 @@ class NotificationService
|
|||
|
||||
# Notify a user when a previously unknown IP or device is used to
|
||||
# sign in to their account
|
||||
def unknown_sign_in(user, ip)
|
||||
def unknown_sign_in(user, ip, time)
|
||||
return unless user.can?(:receive_notifications)
|
||||
|
||||
mailer.unknown_sign_in_email(user, ip).deliver_later
|
||||
mailer.unknown_sign_in_email(user, ip, time).deliver_later
|
||||
end
|
||||
|
||||
# When create an issue we should send an email to:
|
||||
|
|
|
@ -1,14 +1,54 @@
|
|||
%p
|
||||
= _('Hi %{username}!') % { username: sanitize_name(@user.name) }
|
||||
%p
|
||||
= _('A sign-in to your account has been made from the following IP address: %{ip}.') % { ip: @ip }
|
||||
%p
|
||||
- password_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://docs.gitlab.com/ee/user/profile/#changing-your-password' }
|
||||
= _('If you recently signed in and recognize the IP address, you may disregard this email.')
|
||||
= _('If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}.').html_safe % { password_link_start: password_link_start, password_link_end: '</a>'.html_safe }
|
||||
= _('Passwords should be unique and not used for any other sites or services.')
|
||||
- default_font = "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;"
|
||||
- default_style = "#{default_font}font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;"
|
||||
- spacer_style = "#{default_font};height:18px;font-size:18px;line-height:18px;"
|
||||
|
||||
- unless @user.two_factor_enabled?
|
||||
%p
|
||||
- mfa_link_start = '<a href="https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html" target="_blank">'.html_safe
|
||||
= _('To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method.').html_safe % { mfa_link_start: mfa_link_start, mfa_link_end: '</a>'.html_safe }
|
||||
%tr.alert
|
||||
%td{ style: "#{default_font}padding:10px;border-radius:3px;font-size:14px;line-height:1.3;text-align:center;overflow:hidden;color:#ffffff;background-color:#FC6D26;" }
|
||||
%table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;margin:0 auto;" }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ style: "#{default_font}vertical-align:middle;color:#ffffff;text-align:center;" }
|
||||
%span
|
||||
= _("Your %{host} account was signed in to from a new location") % { host: Gitlab.config.gitlab.host }
|
||||
%tr.spacer
|
||||
%td{ style: spacer_style }
|
||||
|
||||
%tr.section
|
||||
%td{ style: "#{default_font};padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
|
||||
%table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" }
|
||||
%tbody
|
||||
%tr
|
||||
%td{ style: default_style }
|
||||
= _('Hostname')
|
||||
%td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;" }
|
||||
= Gitlab.config.gitlab.host
|
||||
%tr
|
||||
%td{ style: "#{default_style}border-top:1px solid #ededed;" }
|
||||
= _('IP Address')
|
||||
%td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
|
||||
%span.muted{ style: "color:#333333;text-decoration:none;" }
|
||||
= @ip
|
||||
%tr
|
||||
%td{ style: "#{default_style}border-top:1px solid #ededed;" }
|
||||
= _('Time')
|
||||
%td{ style: "#{default_style}color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" }
|
||||
= @time.strftime('%Y-%m-%d %l:%M:%S %p %Z')
|
||||
%tr.spacer
|
||||
%td{ style: spacer_style }
|
||||
|
||||
%tr.section
|
||||
%td{ style: "#{default_font};line-height:1.4;text-align:center;padding:0 15px;overflow:hidden;" }
|
||||
%table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;width:100%;" }
|
||||
%tbody
|
||||
%tr{ style: 'width:100%;' }
|
||||
%td{ style: "#{default_style}text-align:center;" }
|
||||
- password_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://docs.gitlab.com/ee/user/profile/#changing-your-password' }
|
||||
= _('If you recently signed in and recognize the IP address, you may disregard this email.')
|
||||
%p
|
||||
= _('If you did not recently sign in, you should immediately %{password_link_start}change your password%{password_link_end}.').html_safe % { password_link_start: password_link_start, password_link_end: '</a>'.html_safe }
|
||||
= _('Passwords should be unique and not used for any other sites or services.')
|
||||
|
||||
- unless @user.two_factor_enabled?
|
||||
%p
|
||||
- mfa_link_start = '<a href="https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html" target="_blank">'.html_safe
|
||||
= _('To further protect your account, consider configuring a %{mfa_link_start}two-factor authentication%{mfa_link_end} method.').html_safe % { mfa_link_start: mfa_link_start, mfa_link_end: '</a>'.html_safe }
|
||||
|
|
|
@ -5,4 +5,6 @@ Rails.application.eager_load!
|
|||
|
||||
ACTION_CABLE_SERVER = true
|
||||
|
||||
use ActionDispatch::RequestId
|
||||
|
||||
run ActionCable.server
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Improve new/unknown sign-in email styling
|
||||
merge_request: 32808
|
||||
author:
|
||||
type: changed
|
|
@ -12,9 +12,9 @@ unless Gitlab::Runtime.sidekiq?
|
|||
config.lograge.logger = ActiveSupport::Logger.new(filename)
|
||||
config.lograge.before_format = lambda do |data, payload|
|
||||
data.delete(:error)
|
||||
data[:db_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:db))
|
||||
data[:view_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:view))
|
||||
data[:duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:duration))
|
||||
data[:db_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:db)) if data[:db]
|
||||
data[:view_duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:view)) if data[:view]
|
||||
data[:duration_s] = Gitlab::Utils.ms_to_round_sec(data.delete(:duration)) if data[:duration]
|
||||
|
||||
data
|
||||
end
|
||||
|
|
|
@ -85,6 +85,29 @@ which correspond to:
|
|||
1. `elasticsearch_calls`: total number of calls to Elasticsearch
|
||||
1. `elasticsearch_duration_s`: total time taken by Elasticsearch calls
|
||||
|
||||
ActionCable connection and subscription events are also logged to this file and they follow the same
|
||||
format above. The `method`, `path`, and `format` fields are not applicable, and are always empty.
|
||||
The ActionCable connection or channel class is used as the `controller`.
|
||||
|
||||
```json
|
||||
{
|
||||
"method":{},
|
||||
"path":{},
|
||||
"format":{},
|
||||
"controller":"IssuesChannel",
|
||||
"action":"subscribe",
|
||||
"status":200,
|
||||
"time":"2020-05-14T19:46:22.008Z",
|
||||
"params":[{"key":"project_path","value":"gitlab/gitlab-foss"},{"key":"iid","value":"1"}],
|
||||
"remote_ip":"127.0.0.1",
|
||||
"user_id":1,
|
||||
"username":"admin",
|
||||
"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:76.0) Gecko/20100101 Firefox/76.0",
|
||||
"correlation_id":"jSOIEynHCUa",
|
||||
"duration_s":0.32566
|
||||
}
|
||||
```
|
||||
|
||||
NOTE: **Note:** Starting with GitLab 12.5, if an error occurs, an
|
||||
`exception` field is included with `class`, `message`, and
|
||||
`backtrace`. Previous versions included an `error` field instead of
|
||||
|
|
|
@ -578,6 +578,18 @@ Additional response parameters:
|
|||
}
|
||||
```
|
||||
|
||||
Users on GitLab [Silver, Premium, or higher](https://about.gitlab.com/pricing/) will also see
|
||||
the `marked_for_deletion_on` attribute:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 4,
|
||||
"description": "Aliquid qui quis dignissimos distinctio ut commodi voluptas est.",
|
||||
"marked_for_deletion_on": "2020-04-03",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
When adding the parameter `with_projects=false`, projects will not be returned.
|
||||
|
||||
```shell
|
||||
|
|
|
@ -20,6 +20,13 @@ that can be reused in different scripts.
|
|||
Variables are useful for customizing your jobs in GitLab CI/CD.
|
||||
When you use variables, you don't have to hard-code values.
|
||||
|
||||
For more information about advanced use of GitLab CI/CD:
|
||||
|
||||
- Get to productivity faster with these [7 advanced GitLab CI workflow hacks](https://about.gitlab.com/webcast/7cicd-hacks/)
|
||||
shared by GitLab engineers.
|
||||
- Learn how the Cloud Native Computing Foundation (CNCF) [eliminates the complexity](https://about.gitlab.com/customers/cncf/)
|
||||
of managing projects across many cloud providers with GitLab CI/CD.
|
||||
|
||||
## Predefined environment variables
|
||||
|
||||
GitLab CI/CD has a [default set of predefined variables](predefined_variables.md)
|
||||
|
|
|
@ -25,6 +25,14 @@ We have complete examples of configuring pipelines:
|
|||
- For a collection of examples, see [GitLab CI/CD Examples](../examples/README.md).
|
||||
- To see a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml).
|
||||
|
||||
For some additional information about GitLab CI/CD:
|
||||
|
||||
- Watch the [CI/CD Ease of configuration](https://www.youtube.com/embed/opdLqwz6tcE) video.
|
||||
- Watch the [Making the case for CI/CD in your organization](https://about.gitlab.com/compare/github-actions-alternative/)
|
||||
webcast to learn the benefits of CI/CD and how to measure the results of CI/CD automation.
|
||||
- Learn how [Verizon reduced rebuilds](https://about.gitlab.com/blog/2019/02/14/verizon-customer-story/)
|
||||
from 30 days to under 8 hours with GitLab.
|
||||
|
||||
NOTE: **Note:**
|
||||
If you have a [mirrored repository where GitLab pulls from](../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter),
|
||||
you may need to enable pipeline triggering in your project's
|
||||
|
|
|
@ -1,7 +1,69 @@
|
|||
# GraphQL
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Helpful Resources
|
||||
|
||||
**General resources**:
|
||||
|
||||
- [📚 Official Introduction to GraphQL](https://graphql.org/learn/)
|
||||
- [📚 Official Introduction to Apollo](https://www.apollographql.com/docs/tutorial/introduction/)
|
||||
|
||||
**GraphQL at GitLab**:
|
||||
|
||||
- [🎬 GitLab Unfiltered GraphQL playlist](https://www.youtube.com/watch?v=wHPKZBDMfxE&list=PL05JrBw4t0KpcjeHjaRMB7IGB2oDWyJzv)
|
||||
- [🎬 GraphQL at GitLab: Deep Dive](../api_graphql_styleguide.md#deep-dive) (video) by Nick Thomas
|
||||
- An overview of the history of GraphQL at GitLab (not frontend-specific)
|
||||
- [🎬 GitLab Feature Walkthrough with GraphQL and Vue Apollo](https://www.youtube.com/watch?v=6yYp2zB7FrM) (video) by Natalia Tepluhina
|
||||
- A real-life example of implmenting a frontend feature in GitLab using GraphQL
|
||||
- [🎬 History of client-side GraphQL at GitLab](https://www.youtube.com/watch?v=mCKRJxvMnf0) (video) Illya Klymov and Natalia Tepluhina
|
||||
- [🎬 From Vuex to Apollo](https://www.youtube.com/watch?v=9knwu87IfU8) (video) by Natalia Tepluhina
|
||||
- A useful overview of when Apollo might be a better choice than Vuex, and how one could go about the transition
|
||||
- [🛠 Vuex-> Apollo Migration: a proof-of-concept project](https://gitlab.com/ntepluhina/vuex-to-apollo/blob/master/README.md)
|
||||
- A collection of examples that show the possible approaches for state management with Vue+GraphQL+(Vuex or Apollo) apps
|
||||
|
||||
### Libraries
|
||||
|
||||
We use [Apollo](https://www.apollographql.com/) (specifically [Apollo Client](https://www.apollographql.com/docs/react/)) and [Vue Apollo](https://github.com/Akryum/vue-apollo/)
|
||||
when using GraphQL for frontend development.
|
||||
|
||||
If you are using GraphQL within a Vue application, the [Usage in Vue](#usage-in-vue) section
|
||||
can help you learn how to integrate Vue Apollo.
|
||||
|
||||
For other usecases, check out the [Usage outside of Vue](#usage-outside-of-vue) section.
|
||||
|
||||
### Tooling
|
||||
|
||||
- [Apollo Client Devtools](https://github.com/apollographql/apollo-client-devtools)
|
||||
|
||||
#### [Apollo GraphQL VS Code extension](https://marketplace.visualstudio.com/items?itemName=apollographql.vscode-apollo)
|
||||
|
||||
If you use VS Code, the Apollo GraphQL extension supports autocompletion in `.graphql` files. To set up
|
||||
the GraphQL extension, follow these steps:
|
||||
|
||||
1. Add an `apollo.config.js` file to the root of your `gitlab` local directory.
|
||||
1. Populate the file with the following content:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
client: {
|
||||
includes: ['./app/assets/javascripts/**/*.graphql', './ee/app/assets/javascripts/**/*.graphql'],
|
||||
service: {
|
||||
name: 'GitLab',
|
||||
localSchemaFile: './doc/api/graphql/reference/gitlab_schema.graphql',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
1. Restart VS Code.
|
||||
|
||||
### Exploring the GraphQL API
|
||||
|
||||
Our GraphQL API can be explored via GraphiQL at your instance's
|
||||
`/-/graphql-explorer` or at [GitLab.com](https://gitlab.com/-/graphql-explorer).
|
||||
`/-/graphql-explorer` or at [GitLab.com](https://gitlab.com/-/graphql-explorer). Consult the
|
||||
[GitLab GraphQL API Reference documentation](../../api/graphql/reference)
|
||||
where needed.
|
||||
|
||||
You can check all existing queries and mutations on the right side
|
||||
of GraphiQL in its **Documentation explorer**. It's also possible to
|
||||
|
@ -10,9 +72,6 @@ their execution by clicking **Execute query** button on the top left:
|
|||
|
||||
![GraphiQL interface](img/graphiql_explorer_v12_4.png)
|
||||
|
||||
We use [Apollo](https://www.apollographql.com/) and [Vue Apollo](https://github.com/vuejs/vue-apollo) for working with GraphQL
|
||||
on the frontend.
|
||||
|
||||
## Apollo Client
|
||||
|
||||
To save duplicated clients getting created in different apps, we have a
|
||||
|
@ -41,7 +100,7 @@ To distinguish queries from mutations and fragments, the following naming conven
|
|||
|
||||
### Fragments
|
||||
|
||||
Fragments are a way to make your complex GraphQL queries more readable and re-usable. Here is an example of GraphQL fragment:
|
||||
[Fragments](https://graphql.org/learn/queries/#fragments) are a way to make your complex GraphQL queries more readable and re-usable. Here is an example of GraphQL fragment:
|
||||
|
||||
```javascript
|
||||
fragment DesignListItem on Design {
|
||||
|
@ -210,7 +269,7 @@ Read more about local state management with Apollo in the [Vue Apollo documentat
|
|||
|
||||
### Using with Vuex
|
||||
|
||||
When Apollo Client is used within Vuex and fetched data is stored in the Vuex store, there is no need in keeping Apollo Client cache enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. More to say, with Apollo default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache passing a valid `fetchPolicy` option to its constructor:
|
||||
When Apollo Client is used within Vuex and fetched data is stored in the Vuex store, there is no need in keeping Apollo Client cache enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. More to say, with Apollo's default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache passing a valid `fetchPolicy` option to its constructor:
|
||||
|
||||
```javascript
|
||||
import fetchPolicies from '~/graphql_shared/fetch_policy_constants';
|
||||
|
@ -587,4 +646,20 @@ defaultClient.query({ query })
|
|||
.then(result => console.log(result));
|
||||
```
|
||||
|
||||
Read more about the [Apollo](https://www.apollographql.com/) client in the [Apollo documentation](https://www.apollographql.com/docs/tutorial/client/).
|
||||
When [using Vuex](#Using-with-Vuex), disable the cache when:
|
||||
|
||||
- The data is being cached elsewhere
|
||||
- The use case does not need caching
|
||||
if the data is being cached elsewhere, or if there is simply no need for it for the given usecase.
|
||||
|
||||
```javascript
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import fetchPolicies from '~/graphql_shared/fetch_policy_constants';
|
||||
|
||||
const defaultClient = createDefaultClient(
|
||||
{},
|
||||
{
|
||||
fetchPolicy: fetchPolicies.NO_CACHE,
|
||||
},
|
||||
);
|
||||
```
|
||||
|
|
|
@ -18,10 +18,10 @@ Prior to this, Go did not have any well-defined mechanism for version management
|
|||
While 3rd party version management tools existed, the default Go experience had
|
||||
no support for versioning.
|
||||
|
||||
Go modules use semantic versioning. The versions of a module are defined as VCS
|
||||
tags that are valid semantic versions prefixed with `v`. For example, to release
|
||||
version `1.0.0` of `gitlab.com/my/project`, the developer must create the Git
|
||||
tag `v1.0.0`.
|
||||
Go modules use [semantic versioning](https://semver.org). The versions of a
|
||||
module are defined as VCS (version control system) tags that are valid semantic
|
||||
versions prefixed with `v`. For example, to release version `1.0.0` of
|
||||
`gitlab.com/my/project`, the developer must create the Git tag `v1.0.0`.
|
||||
|
||||
For major versions other than 0 and 1, the module name must be suffixed with
|
||||
`/vX` where X is the major version. For example, version `v2.0.0` of
|
||||
|
@ -38,6 +38,10 @@ end with a timestamp and the first 12 characters of the commit identifier:
|
|||
|
||||
If a VCS tag matches one of these patterns, it is ignored.
|
||||
|
||||
For a complete understanding of Go modules and versioning, see [this series of
|
||||
blog posts](https://blog.golang.org/using-go-modules) on the official Go
|
||||
website.
|
||||
|
||||
## 'Module' vs 'Package'
|
||||
|
||||
- A package is a folder containing `*.go` files.
|
||||
|
|
|
@ -62,6 +62,7 @@ are very appreciative of the work done by translators and proofreaders!
|
|||
- Hiroyuki Sato - [GitLab](https://gitlab.com/hiroponz), [CrowdIn](https://crowdin.com/profile/hiroponz)
|
||||
- Tomo Dote - [GitLab](https://gitlab.com/fu7mu4), [CrowdIn](https://crowdin.com/profile/fu7mu4)
|
||||
- Hiromi Nozawa - [GitLab](https://gitlab.com/hir0mi), [CrowdIn](https://crowdin.com/profile/hir0mi)
|
||||
- Takuya Noguchi - [GitLab](https://gitlab.com/tnir), [CrowdIn](https://crowdin.com/profile/tnir)
|
||||
- Korean
|
||||
- Chang-Ho Cha - [GitLab](https://gitlab.com/changho-cha), [CrowdIn](https://crowdin.com/profile/zzazang)
|
||||
- Ji Hun Oh - [GitLab](https://gitlab.com/Baw-Appie), [CrowdIn](https://crowdin.com/profile/BawAppie)
|
||||
|
|
|
@ -54,7 +54,40 @@ NOTE: **Note:**
|
|||
GitLab does not currently display Go modules in the **Packages Registry** of a project.
|
||||
Follow [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/213770) for details.
|
||||
|
||||
### Fetch modules from private projects
|
||||
## Add GitLab as a Go proxy
|
||||
|
||||
NOTE: **Note:**
|
||||
To use a Go proxy, you must be using Go 1.13 or later.
|
||||
|
||||
The available proxy endpoints are:
|
||||
|
||||
- Project - can fetch modules defined by a project - `/api/v4/projects/:id/packages/go`
|
||||
|
||||
To use the Go proxy for GitLab to fetch Go modules from GitLab, add the
|
||||
appropriate proxy endpoint to `GOPROXY`. For details on setting Go environment
|
||||
variables, see [Set environment variables](#set-environment-variables). For
|
||||
details on configuring `GOPROXY`, see [Dependency Management in Go >
|
||||
Proxies](../../../development/go_guide/dependencies.md#proxies).
|
||||
|
||||
For example, adding the project-specific endpoint to `GOPROXY` will tell Go
|
||||
to initially query that endpoint and fall back to the default behavior:
|
||||
|
||||
```shell
|
||||
go env -w GOPROXY='https://gitlab.com/api/v4/projects/1234/packages/go,https://proxy.golang.org,direct'
|
||||
```
|
||||
|
||||
With this configuration, Go fetches dependencies as follows:
|
||||
|
||||
1. Attempt to fetch from the project-specific Go proxy.
|
||||
1. Attempt to fetch from [proxy.golang.org](https://proxy.golang.org).
|
||||
1. Fetch directly with version control system operations (such as `git clone`,
|
||||
`svn checkout`, and so on).
|
||||
|
||||
If `GOPROXY` is not specified, Go follows steps 2 and 3, which corresponds to
|
||||
setting `GOPROXY` to `https://proxy.golang.org,direct`. If `GOPROXY` only
|
||||
contains the project-specific endpoint, Go will only query that endpoint.
|
||||
|
||||
## Fetch modules from private projects
|
||||
|
||||
`go` does not support transmitting credentials over insecure connections. The
|
||||
steps below work only if GitLab is configured for HTTPS.
|
||||
|
@ -64,7 +97,7 @@ steps below work only if GitLab is configured for HTTPS.
|
|||
1. Configure Go to skip downloading of checksums for private GitLab projects
|
||||
from the public checksum database.
|
||||
|
||||
#### Enable Request Authentication
|
||||
### Enable request authentication
|
||||
|
||||
Create a [personal access token](../../profile/personal_access_tokens.md) with
|
||||
the `api` or `read_api` scope and add it to
|
||||
|
@ -78,90 +111,53 @@ machine <url> login <username> password <token>
|
|||
`<username>` and `<token>` should be your username and the personal access
|
||||
token, respectively.
|
||||
|
||||
#### Disable checksum database queries
|
||||
### Disable checksum database queries
|
||||
|
||||
Go can be configured to query a checksum database for module checksums. Go 1.13
|
||||
and later query `sum.golang.org` by default. This fails for modules that are not
|
||||
public and thus not accessible to `sum.golang.org`. To resolve this issue, set
|
||||
`GONOSUMDB` to a comma-separated list of projects or namespaces for which Go
|
||||
should not query the checksum database. For example, `go env -w
|
||||
GONOSUMDB=gitlab.com/my/project` persistently configures Go to skip checksum
|
||||
queries for the project `gitlab.com/my/project`.
|
||||
When downloading dependencies, by default Go 1.13 and later validate fetched
|
||||
sources against the checksum database `sum.golang.org`. If the checksum of the
|
||||
fetched sources does not match the checksum from the database, Go will not build
|
||||
the dependency. This causes private modules to fail to build, as
|
||||
`sum.golang.org` cannot fetch the source of private modules and thus cannot
|
||||
provide a checksum. To resolve this issue, `GONOSUMDB` should be set to a
|
||||
comma-separated list of private projects. For details on setting Go environment
|
||||
variables, see [Set environment variables](#set-environment-variables). For more
|
||||
details on disabling this feature of Go, see [Dependency Management in Go >
|
||||
Checksums](../../../development/go_guide/dependencies.md#checksums).
|
||||
|
||||
Checksum database queries can be disabled for arbitrary prefixes or disabled
|
||||
entirely. However, checksum database queries are a security mechanism and as
|
||||
such they should be disabled selectively and only when necessary. `GOSUMDB=off`
|
||||
or `GONOSUMDB=*` disables checksum queries entirely. `GONOSUMDB=gitlab.com`
|
||||
disables checksum queries for all projects hosted on GitLab.com.
|
||||
|
||||
## Add GitLab as a Go proxy
|
||||
|
||||
NOTE: **Note:**
|
||||
To use a Go proxy, you must be using Go 1.13 or later.
|
||||
|
||||
The available proxy endpoints are:
|
||||
|
||||
- Project - can fetch modules defined by a project - `/api/v4/projects/:id/packages/go`
|
||||
|
||||
Go's use of proxies is configured with the `GOPROXY` environment variable, as a
|
||||
comma separated list of URLs. Go 1.14 adds support for comma separated list of
|
||||
URLs. Go 1.14 adds support for using `go env -w` to manage Go's environment
|
||||
variables. For example, `go env -w GOPROXY=...` writes to `$GOPATH/env`
|
||||
(which defaults to `~/.go/env`). `GOPROXY` can also be configured as a normal
|
||||
environment variable, with RC files or `export GOPROXY=...`.
|
||||
|
||||
The default value of `$GOPROXY` is `https://proxy.golang.org,direct`, which
|
||||
tells `go` to first query `proxy.golang.org` and fallback to direct VCS
|
||||
operations (`git clone`, `svc checkout`, etc). Replacing
|
||||
`https://proxy.golang.org` with a GitLab endpoint will direct all fetches
|
||||
through GitLab. Currently GitLab's Go proxy does not support dependency
|
||||
proxying, so all external dependencies will be handled directly. If GitLab's
|
||||
endpoint is inserted before `https://proxy.golang.org`, then all fetches will
|
||||
first go through GitLab. This can help avoid making requests for private
|
||||
packages to the public proxy, but `GOPRIVATE` is a much safer way of achieving
|
||||
that.
|
||||
|
||||
For example, with the following configuration, Go will attempt to fetch modules
|
||||
from 1) GitLab project 1234's Go module proxy, 2) `proxy.golang.org`, and
|
||||
finally 3) directly with Git (or another VCS, depending on where the module
|
||||
source is hosted).
|
||||
For example, to disable checksum queries for `gitlab.com/my/project`, set `GONOSUMDB`:
|
||||
|
||||
```shell
|
||||
go env -w GOPROXY=https://gitlab.com/api/v4/projects/1234/packages/go,https://proxy.golang.org,direct
|
||||
go env -w GONOSUMDB='gitlab.com/my/project,<previous value>'
|
||||
```
|
||||
|
||||
## Release a module
|
||||
## Working with Go
|
||||
|
||||
Go modules and module versions are handled entirely with Git (or SVN, Mercurial,
|
||||
and so on). A module is a repository containing Go source and a `go.mod` file. A
|
||||
version of a module is a Git tag (or equivalent) that is a valid [semantic
|
||||
version](https://semver.org), prefixed with 'v'. For example, `v1.0.0` and
|
||||
`v1.3.2-alpha` are valid module versions, but `v1` or `v1.2` are not.
|
||||
If you are unfamiliar with managing dependencies in Go, or Go in general,
|
||||
consider reviewing the following documentation:
|
||||
|
||||
Go requires that major versions after v1 involve a change in the import path of
|
||||
the module. For example, version 2 of the module `gitlab.com/my/project` must be
|
||||
imported and released as `gitlab.com/my/project/v2`.
|
||||
- [Dependency Management in Go](../../../development/go_guide/dependencies.md)
|
||||
- [Go Modules Reference](https://golang.org/ref/mod)
|
||||
- [Documentation (golang.org)](https://golang.org/doc/)
|
||||
- [Learn (learn.go.dev)](https://learn.go.dev/)
|
||||
|
||||
For a complete understanding of Go modules and versioning, see [this series of
|
||||
blog posts](https://blog.golang.org/using-go-modules) on the official Go
|
||||
website.
|
||||
### Set environment variables
|
||||
|
||||
## Valid modules and versions
|
||||
Go uses environment variables to control various features. These can be managed
|
||||
in all the usual ways, but Go 1.14 will read and write Go environment variables
|
||||
from and to a special Go environment file, `~/.go/env` by default. If `GOENV` is
|
||||
set to a file, Go will read and write that file instead. If `GOENV` is not set
|
||||
but `GOPATH` is set, Go will read and write `$GOPATH/env`.
|
||||
|
||||
The GitLab Go proxy will ignore modules and module versions that have an invalid
|
||||
`module` directive in their `go.mod`. Go requires that a package imported as
|
||||
`gitlab.com/my/project` can be accessed with that same URL, and that the first
|
||||
line of `go.mod` is `module gitlab.com/my/project`. If `go.mod` names a
|
||||
different module, compilation will fail. Additionally, Go requires, for major
|
||||
versions after 1, that the name of the module have an appropriate suffix, for
|
||||
example `gitlab.com/my/project/v2`. If the `module` directive does not also have
|
||||
this suffix, compilation will fail.
|
||||
Go environment variables can be read with `go env <var>` and, in Go 1.14 and
|
||||
later, can be written with `go env -w <var>=<value>`. For example, `go env
|
||||
GOPATH` or `go env -w GOPATH=/go`.
|
||||
|
||||
Go supports 'pseudo-versions' that encode the timestamp and SHA of a commit.
|
||||
Tags that match the pseudo-version pattern are ignored, as otherwise they could
|
||||
interfere with fetching specific commits using a pseudo-version. Pseudo-versions
|
||||
follow one of three formats:
|
||||
### Release a module
|
||||
|
||||
- `vX.0.0-yyyymmddhhmmss-abcdefabcdef`, when no earlier tagged commit exists for X.
|
||||
- `vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef`, when most recent prior tag is vX.Y.Z-pre.
|
||||
- `vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef`, when most recent prior tag is vX.Y.Z.
|
||||
Go modules and module versions are defined by source repositories, such as Git,
|
||||
SVN, Mercurial, and so on. A module is a repository containing `go.mod` and Go
|
||||
files. Module versions are defined by VCS tags. To publish a module, push
|
||||
`go.mod` and source files to a VCS repository. To publish a module version, push
|
||||
a VCS tag. See [Dependency Management in Go >
|
||||
Versioning](../../../development/go_guide/dependencies.md#versioning) for more
|
||||
details on what constitutes a valid module or module version.
|
||||
|
|
BIN
doc/user/profile/img/unknown_sign_in_email_v13_1.png
Normal file
BIN
doc/user/profile/img/unknown_sign_in_email_v13_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -1,5 +1,7 @@
|
|||
# Email notification for unknown sign-ins
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27211) in GitLab 13.0.
|
||||
|
||||
When a user successfully signs in from a previously unknown IP address,
|
||||
GitLab notifies the user by email. In this way, GitLab proactively alerts users of potentially
|
||||
malicious or unauthorized sign-ins.
|
||||
|
@ -13,4 +15,4 @@ There are two methods used to identify a known sign-in:
|
|||
|
||||
## Example email
|
||||
|
||||
![Unknown sign in email](./img/unknown_sign_in_email_v13_0.png)
|
||||
![Unknown sign in email](./img/unknown_sign_in_email_v13_1.png)
|
||||
|
|
|
@ -67,6 +67,8 @@ A link is any URL which can point to whatever you like; documentation, built
|
|||
binaries, or other related materials. These can be both internal or external
|
||||
links from your GitLab instance.
|
||||
|
||||
The four types of links are "Runbook," "Package," "Image," and "Other."
|
||||
|
||||
#### Permanent links to Release assets
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27300) in GitLab 12.9.
|
||||
|
|
|
@ -19,17 +19,17 @@ module Gitlab
|
|||
remote_ip: event.payload[:remote_ip],
|
||||
user_id: event.payload[:user_id],
|
||||
username: event.payload[:username],
|
||||
ua: event.payload[:ua],
|
||||
queue_duration_s: event.payload[:queue_duration_s]
|
||||
ua: event.payload[:ua]
|
||||
}
|
||||
|
||||
payload.merge!(event.payload[:metadata]) if event.payload[:metadata]
|
||||
|
||||
::Gitlab::InstrumentationHelper.add_instrumentation_data(payload)
|
||||
|
||||
payload[:queue_duration_s] = event.payload[:queue_duration_s] if event.payload[:queue_duration_s]
|
||||
payload[:response] = event.payload[:response] if event.payload[:response]
|
||||
payload[:etag_route] = event.payload[:etag_route] if event.payload[:etag_route]
|
||||
payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id
|
||||
payload[Labkit::Correlation::CorrelationId::LOG_KEY] = event.payload[Labkit::Correlation::CorrelationId::LOG_KEY] || Labkit::Correlation::CorrelationId.current_id
|
||||
|
||||
if cpu_s = Gitlab::Metrics::System.thread_cpu_duration(::Gitlab::RequestContext.instance.start_thread_cpu_time)
|
||||
payload[:cpu_s] = cpu_s.round(2)
|
||||
|
|
|
@ -358,6 +358,9 @@ msgstr ""
|
|||
msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
|
||||
msgstr ""
|
||||
|
||||
msgid "%{host} sign-in from new location"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{icon}You are about to add %{usersTag} people to the discussion. Proceed with caution."
|
||||
msgstr ""
|
||||
|
||||
|
@ -968,9 +971,6 @@ msgstr ""
|
|||
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
|
||||
msgstr ""
|
||||
|
||||
msgid "A sign-in to your account has been made from the following IP address: %{ip}."
|
||||
msgstr ""
|
||||
|
||||
msgid "A subscription will trigger a new pipeline on the default branch of this project when a pipeline successfully completes for a new tag on the %{default_branch_docs} of the subscribed project."
|
||||
msgstr ""
|
||||
|
||||
|
@ -11405,6 +11405,9 @@ msgstr ""
|
|||
msgid "Hook was successfully updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "Hostname"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hour (UTC)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -23531,9 +23534,6 @@ msgstr ""
|
|||
msgid "Unknown response text"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown sign-in from new location"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unlimited"
|
||||
msgstr ""
|
||||
|
||||
|
@ -25535,6 +25535,9 @@ msgstr ""
|
|||
msgid "YouTube"
|
||||
msgstr ""
|
||||
|
||||
msgid "Your %{host} account was signed in to from a new location"
|
||||
msgstr ""
|
||||
|
||||
msgid "Your %{strong}%{plan_name}%{strong_close} subscription for %{strong}%{namespace_name}%{strong_close} will expire on %{strong}%{expires_on}%{strong_close}."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ describe IssuesChannel do
|
|||
end
|
||||
|
||||
it 'rejects when the user does not have access' do
|
||||
stub_connection current_user: nil
|
||||
stub_action_cable_connection current_user: nil
|
||||
|
||||
subscribe(project_path: issue.project.full_path, iid: issue.iid)
|
||||
|
||||
|
@ -26,7 +26,7 @@ describe IssuesChannel do
|
|||
end
|
||||
|
||||
it 'subscribes to a stream when the user has access' do
|
||||
stub_connection current_user: issue.author
|
||||
stub_action_cable_connection current_user: issue.author
|
||||
|
||||
subscribe(project_path: issue.project.full_path, iid: issue.iid)
|
||||
|
||||
|
|
37
spec/features/action_cable_logging_spec.rb
Normal file
37
spec/features/action_cable_logging_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'ActionCable logging', :js do
|
||||
let_it_be(:project) { create(:project, :public) }
|
||||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before_all do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it 'adds extra context to logs' do
|
||||
allow(ActiveSupport::Notifications).to receive(:instrument).and_call_original
|
||||
|
||||
expect(ActiveSupport::Notifications).to receive(:instrument).with(
|
||||
'connect.action_cable',
|
||||
a_hash_including(remote_ip: '127.0.0.1', user_id: nil, username: nil)
|
||||
)
|
||||
|
||||
subscription_data = a_hash_including(
|
||||
remote_ip: '127.0.0.1',
|
||||
user_id: user.id,
|
||||
username: user.username,
|
||||
params: a_hash_including(
|
||||
project_path: project.full_path,
|
||||
iid: issue.iid.to_s
|
||||
)
|
||||
)
|
||||
|
||||
expect(ActiveSupport::Notifications).to receive(:instrument).with('subscribe.action_cable', subscription_data)
|
||||
|
||||
gitlab_sign_in(user)
|
||||
visit project_issue_path(project, issue)
|
||||
end
|
||||
end
|
|
@ -99,7 +99,7 @@ describe 'lograge', type: :request do
|
|||
end
|
||||
|
||||
context 'with a log subscriber' do
|
||||
let(:subscriber) { Lograge::RequestLogSubscriber.new }
|
||||
let(:subscriber) { Lograge::LogSubscribers::ActionController.new }
|
||||
|
||||
let(:event) do
|
||||
ActiveSupport::Notifications::Event.new(
|
||||
|
|
|
@ -13,21 +13,16 @@ describe Gitlab::Lograge::CustomOptions do
|
|||
}
|
||||
end
|
||||
|
||||
let(:event) do
|
||||
ActiveSupport::Notifications::Event.new(
|
||||
'test',
|
||||
1,
|
||||
2,
|
||||
'transaction_id',
|
||||
{
|
||||
params: params,
|
||||
user_id: 'test',
|
||||
cf_ray: SecureRandom.hex,
|
||||
cf_request_id: SecureRandom.hex,
|
||||
metadata: { 'meta.user' => 'jane.doe' }
|
||||
}
|
||||
)
|
||||
let(:event_payload) do
|
||||
{
|
||||
params: params,
|
||||
user_id: 'test',
|
||||
cf_ray: SecureRandom.hex,
|
||||
cf_request_id: SecureRandom.hex,
|
||||
metadata: { 'meta.user' => 'jane.doe' }
|
||||
}
|
||||
end
|
||||
let(:event) { ActiveSupport::Notifications::Event.new('test', 1, 2, 'transaction_id', event_payload) }
|
||||
|
||||
subject { described_class.call(event) }
|
||||
|
||||
|
@ -63,19 +58,23 @@ describe Gitlab::Lograge::CustomOptions do
|
|||
end
|
||||
|
||||
context 'when metadata is missing' do
|
||||
let(:event) do
|
||||
ActiveSupport::Notifications::Event.new(
|
||||
'test',
|
||||
1,
|
||||
2,
|
||||
'transaction_id',
|
||||
{ params: {} }
|
||||
)
|
||||
end
|
||||
let(:event_payload) { { params: {} } }
|
||||
|
||||
it 'does not break' do
|
||||
expect { subject }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when correlation_id is overriden' do
|
||||
let(:correlation_id_key) { Labkit::Correlation::CorrelationId::LOG_KEY }
|
||||
|
||||
before do
|
||||
event_payload[correlation_id_key] = '123456'
|
||||
end
|
||||
|
||||
it 'sets the overriden value' do
|
||||
expect(subject[correlation_id_key]).to eq('123456')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -160,38 +160,48 @@ describe Emails::Profile do
|
|||
describe 'user unknown sign in email' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:ip) { '169.0.0.1' }
|
||||
let_it_be(:current_time) { Time.current }
|
||||
let_it_be(:email) { Notify.unknown_sign_in_email(user, ip, current_time) }
|
||||
|
||||
subject { Notify.unknown_sign_in_email(user, ip) }
|
||||
subject { email }
|
||||
|
||||
it_behaves_like 'an email sent from GitLab'
|
||||
it_behaves_like 'it should not have Gmail Actions links'
|
||||
it_behaves_like 'a user cannot unsubscribe through footer link'
|
||||
|
||||
it 'is sent to the user' do
|
||||
expect(subject).to deliver_to user.email
|
||||
is_expected.to deliver_to user.email
|
||||
end
|
||||
|
||||
it 'has the correct subject' do
|
||||
expect(subject).to have_subject /^Unknown sign-in from new location$/
|
||||
is_expected.to have_subject "#{Gitlab.config.gitlab.host} sign-in from new location"
|
||||
end
|
||||
|
||||
it 'mentions the unknown sign-in IP' do
|
||||
expect(subject).to have_body_text /A sign-in to your account has been made from the following IP address: #{ip}./
|
||||
it 'mentions the new sign-in IP' do
|
||||
is_expected.to have_body_text ip
|
||||
end
|
||||
|
||||
it 'includes a link to the change password page' do
|
||||
expect(subject).to have_body_text /#{edit_profile_password_path}/
|
||||
it 'mentioned the time' do
|
||||
is_expected.to have_body_text current_time.strftime('%Y-%m-%d %l:%M:%S %p %Z')
|
||||
end
|
||||
|
||||
it 'includes a link to the change password documentation' do
|
||||
is_expected.to have_body_text 'https://docs.gitlab.com/ee/user/profile/#changing-your-password'
|
||||
end
|
||||
|
||||
it 'mentions two factor authentication when two factor is not enabled' do
|
||||
expect(subject).to have_body_text /two-factor authentication/
|
||||
is_expected.to have_body_text 'two-factor authentication'
|
||||
end
|
||||
|
||||
it 'includes a link to two-factor authentication documentation' do
|
||||
is_expected.to have_body_text 'https://docs.gitlab.com/ee/user/profile/account/two_factor_authentication.html'
|
||||
end
|
||||
|
||||
context 'when two factor authentication is enabled' do
|
||||
it 'does not mention two factor authentication' do
|
||||
two_factor_user = create(:user, :two_factor)
|
||||
let(:user) { create(:user, :two_factor) }
|
||||
|
||||
expect( Notify.unknown_sign_in_email(two_factor_user, ip) )
|
||||
it 'does not mention two factor authentication' do
|
||||
expect( Notify.unknown_sign_in_email(user, ip, current_time) )
|
||||
.not_to have_body_text /two-factor authentication/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_shared_state do
|
|||
double(:request, {
|
||||
user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 ' \
|
||||
'(KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]',
|
||||
ip: '127.0.0.1',
|
||||
remote_ip: '127.0.0.1',
|
||||
session: session
|
||||
})
|
||||
end
|
||||
|
|
|
@ -243,11 +243,12 @@ describe NotificationService, :mailer do
|
|||
describe '#unknown_sign_in' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:ip) { '127.0.0.1' }
|
||||
let_it_be(:time) { Time.current }
|
||||
|
||||
subject { notification.unknown_sign_in(user, ip) }
|
||||
subject { notification.unknown_sign_in(user, ip, time) }
|
||||
|
||||
it 'sends email to the user' do
|
||||
expect { subject }.to have_enqueued_email(user, ip, mail: 'unknown_sign_in_email')
|
||||
expect { subject }.to have_enqueued_email(user, ip, time, mail: 'unknown_sign_in_email')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ RSpec.configure do |config|
|
|||
config.include IdempotentWorkerHelper, type: :worker
|
||||
config.include RailsHelpers
|
||||
config.include SidekiqMiddleware
|
||||
config.include StubActionCableConnection, type: :channel
|
||||
|
||||
if ENV['CI'] || ENV['RETRIES']
|
||||
# This includes the first try, i.e. tests will be run 4 times before failing.
|
||||
|
|
7
spec/support/action_cable.rb
Normal file
7
spec/support/action_cable.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.before(:each, type: :channel) do
|
||||
stub_action_cable_connection
|
||||
end
|
||||
end
|
7
spec/support/helpers/stub_action_cable_connection.rb
Normal file
7
spec/support/helpers/stub_action_cable_connection.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module StubActionCableConnection
|
||||
def stub_action_cable_connection(current_user: nil, request: ActionDispatch::TestRequest.create)
|
||||
stub_connection(current_user: current_user, request: request)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue