darjeelink 0.11.8 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f077cd42297ac6611f454687f572c0ba3b2b5b0e6adbaedbbcae1bd905b16c8
4
- data.tar.gz: 5b7879fc14f7e65438b3196a20f05d3a052f43aa3959617f8cb0276c59a7aaf1
3
+ metadata.gz: ca8f37399422052422670335b4e69c6f52de45549aa93ec34311b29347aab47d
4
+ data.tar.gz: 204d687368b9708e6ef8b6f0b06318bffd7fac0ad177b7f4cdfc5b44d415b3c2
5
5
  SHA512:
6
- metadata.gz: 5a69637a14edf0be055e45e615117c794dfc5bb6d86661d1e92105d56dc874a12542a667fc0f27a5edc983c0e26662f5411cb01c99b82278356f1b91011e9319
7
- data.tar.gz: 46d895118941de94c2b2134d809003d7c63c3acbb6fb0e581ad4c23b27c818f3c70d9cf1ee77ad00407a3be83111915429c735630ba597161c7290ed99ac6f84
6
+ metadata.gz: cd1b3cc45ccb146106aa6acd72aa625269e4730432078c1bb803b4179bf9095b2aa5fa42f3960e6570235b9a280fc318772fdade81ccd77a566a1f1dcb6550e4
7
+ data.tar.gz: 848a20765a23dde62eb9c3f937c4384917577e78af8bca65417c3ae17cc447011c021aaae9bb7eabde13e114daaa0a8522ba10270c9943a96b7d5a1ce561c4be
data/README.md CHANGED
@@ -19,6 +19,48 @@ There is a UTM generator, where you can provide:
19
19
  - a campaign identifier
20
20
  And you can get a link with UTM params all filled in, and shortern it with one click.
21
21
 
22
+ ## API
23
+ There is an API available to create short links.
24
+ To create a short link via the API:
25
+
26
+ First, create an api token `Darjeelink::ApiToken.create!(username: <username>, active: true)`.
27
+ Then grab the token.
28
+
29
+ Next, make a request
30
+ ```
31
+ POST /api
32
+ Authorization => Token token=<username>:<token>
33
+ {
34
+ short_link: {
35
+ url: 'https://www.example.com',
36
+ shortened_path: 'xmpl' (optional)
37
+ }
38
+ }
39
+ ```
40
+ `url` is the absolute URI that you wish to shorten
41
+ `shortened_path` is the path that you will visit to get redirected to your original link. It is optional. If it is not provided one will be generated automatically
42
+
43
+ If successful you will get a response like:
44
+ ```
45
+ STATUS 201
46
+ {
47
+ short_link: <shortened_url>
48
+ }
49
+ ```
50
+
51
+ If unsuccessful you will get a response like
52
+ ```
53
+ STATUS 400
54
+ {
55
+ error: "information on what went wrong"
56
+ }
57
+ ```
58
+
59
+ If authorization failed you will get a response like
60
+ ```
61
+ STATUS 401
62
+ {}
63
+ ```
22
64
  ## Installation
23
65
  ### Gemfile
24
66
  Add these lines to your app's Gemfile
@@ -72,6 +114,20 @@ Run `cp .env.sample spec/dummy/.env.test`
72
114
 
73
115
  Change the database url to be different to the development one i.e. `postgres://darjeelink_dbuser:password@localhost/darjeelink-test`
74
116
 
117
+ ## Releasing
118
+ Darjeelink follows [Semantic Versioning](https://semver.org)
119
+
120
+ Once all necessary changes have made it in to master and you are ready to do a release you need to do these steps.
121
+
122
+ Note that if you are running in a vagrant VM, most of these steps can be done from within the VM.
123
+
124
+ - Update `lib/darjeelink/version.rb` to the new version
125
+ - Run `bundle install` to pick up the change in Gemfile.lock
126
+ - Commit the changes to `lib/darjeelink/version.rb` and `Gemfile.lock`, and push them to GitHub
127
+ - Go to `https://github.com/38degrees/darjeelink/releases` and create a release tag in GitHub
128
+ - Run `gem build darjeelink.gemspec` this will output a file `darjeelink-X.X.X.gem` the version should match what version.rb and github.
129
+ - Run `gem push darjeelink-X.X.X.gem`
130
+
75
131
  ## GDPR
76
132
  No personally identifiable data is stored about the public by this gem.
77
133
  It does not store information on individual clicks, only a counter of how many times a link has been clicked.
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Darjeelink
4
+ class ApiController < Darjeelink::ApplicationController
5
+ skip_before_action :check_ip_whitelist
6
+ skip_before_action :authenticate
7
+
8
+ before_action :authenticate_token
9
+
10
+ def create
11
+ short_link = Darjeelink::ShortLink.create!(short_link_params)
12
+
13
+ render(
14
+ json: { short_link: "#{Darjeelink.domain}/#{short_link.shortened_path}" },
15
+ status: :created
16
+ )
17
+ rescue ActiveRecord::RecordNotUnique
18
+ render(
19
+ json: { error: "#{short_link_params[:shortened_path]} already used! Choose a different custom path" },
20
+ status: :bad_request
21
+ )
22
+ rescue ActiveRecord::RecordInvalid => e
23
+ render(
24
+ json: { error: e.message.to_s },
25
+ status: :bad_request
26
+ )
27
+ rescue ActionController::ParameterMissing
28
+ render(
29
+ json: { error: 'Missing required params' },
30
+ status: :bad_request
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def short_link_params
37
+ params.require(:short_link).permit(:url, :shortened_path)
38
+ end
39
+
40
+ def authenticate_token
41
+ # The Authorization header must be supplied in the following format:
42
+ # "Authorization" => "Token token=#{username}:#{token}"
43
+ authenticate_or_request_with_http_token do |username_token, _options|
44
+ # Perform token comparison; avoid timing attacks and length leaks
45
+ # See: https://thisdata.com/blog/timing-attacks-against-string-comparison/
46
+ return head(:unauthorized) unless valid_authorization_token?(username_token)
47
+
48
+ return true
49
+ end
50
+ end
51
+
52
+ def valid_authorization_token?(username_token)
53
+ username, token = username_token.split ':'
54
+
55
+ stored_token = ApiToken.find_by(username: username, active: true)&.token
56
+ return false if stored_token.nil?
57
+
58
+ ActiveSupport::SecurityUtils.secure_compare(
59
+ token,
60
+ stored_token
61
+ )
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Darjeelink
4
+ class ApiToken < ApplicationRecord
5
+ validates :username, uniqueness: true
6
+ validates :token, length: { minimum: 32 }, uniqueness: true
7
+
8
+ before_validation :generate_token
9
+
10
+ def generate_token
11
+ self.token = SecureRandom.uuid if token.blank?
12
+ end
13
+ end
14
+ end
@@ -50,7 +50,7 @@ module Darjeelink
50
50
  i /= base
51
51
  end
52
52
 
53
- generated_path.join('').reverse
53
+ generated_path.join.reverse
54
54
  end
55
55
  end
56
56
  end
@@ -0,0 +1,26 @@
1
+ {
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "Mass Assignment",
5
+ "warning_code": 70,
6
+ "fingerprint": "4c710243b0d9f3f174b1b0b465dcd19aca14b1f1a9658572b13a1172855b6ed7",
7
+ "check_name": "MassAssignment",
8
+ "message": "Parameters should be whitelisted for mass assignment",
9
+ "file": "app/controllers/darjeelink/short_links_controller.rb",
10
+ "line": 83,
11
+ "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
12
+ "code": "params.permit!",
13
+ "render_path": null,
14
+ "location": {
15
+ "type": "method",
16
+ "class": "Darjeelink::ShortLinksController",
17
+ "method": "build_url"
18
+ },
19
+ "user_input": null,
20
+ "confidence": "Medium",
21
+ "note": "The params aren't being use to create a record, we just use it to merge params that might be present on the shortened url and the source url"
22
+ }
23
+ ],
24
+ "updated": "2020-07-23 16:52:33 +0000",
25
+ "brakeman_version": "4.8.2"
26
+ }
@@ -14,14 +14,17 @@ Darjeelink.configure do |config|
14
14
  'sms-blast': 'SMS Blast',
15
15
  'google-advert': 'Google advert',
16
16
  'instagram-advert': 'Instagram Advert',
17
- 'chatbot': 'Chatbot',
18
- 'template': 'Template',
19
- 'other': 'Other',
20
- 'spotify': 'Spotify',
21
- 'youtube': 'Youtube',
17
+ 'instagram-post': 'Instagram Post',
18
+ 'instagram-story': 'Instagram Story',
19
+ chatbot: 'Chatbot',
20
+ template: 'Template',
21
+ other: 'Other',
22
+ spotify: 'Spotify',
23
+ youtube: 'Youtube',
22
24
  'google-search': 'Google search',
23
25
  'google-display': 'Google display',
24
- 'snapchat-advert': 'Snapchat Advert'
26
+ 'snapchat-advert': 'Snapchat Advert',
27
+ 'digitalorganiser-share': 'Digital Organiser'
25
28
  }
26
29
 
27
30
  config.auth_domain = ENV['AUTH_DOMAIN']
data/config/routes.rb CHANGED
@@ -5,6 +5,7 @@ Darjeelink::Engine.routes.draw do
5
5
 
6
6
  resources :short_links
7
7
  resources :tracking_links, only: :new
8
+ resources :api, only: :create
8
9
 
9
10
  # OmniAuth
10
11
  get '/auth/:provider/callback', to: 'sessions#create'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateDarjeelinkApiTokens < ActiveRecord::Migration[6.1]
4
+ def change
5
+ create_table :darjeelink_api_tokens do |t|
6
+ t.string :token, null: false
7
+ t.string :username, null: false
8
+ t.boolean :active, null: false, default: false
9
+ t.timestamps
10
+ end
11
+
12
+ add_index(:darjeelink_api_tokens, :username, unique: true)
13
+ add_index(:darjeelink_api_tokens, :token, unique: true)
14
+ end
15
+ end
@@ -2,11 +2,7 @@
2
2
 
3
3
  module Darjeelink
4
4
  class Configuration
5
- attr_accessor :domain
6
- attr_accessor :source_mediums
7
- attr_accessor :auth_domain
8
- attr_accessor :rebrandly_api_key
9
- attr_accessor :fallback_url
5
+ attr_accessor :domain, :source_mediums, :auth_domain, :rebrandly_api_key, :fallback_url
10
6
 
11
7
  def initialize
12
8
  @domain = nil
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Darjeelink
4
- VERSION = '0.11.8'
4
+ VERSION = '0.13.0'
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: darjeelink
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.8
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Hulme
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-17 00:00:00.000000000 Z
11
+ date: 2021-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: omniauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: omniauth-google-oauth2
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +58,14 @@ dependencies:
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '5'
61
+ version: '6'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '5'
68
+ version: '6'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rebrandly
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: brakeman
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: bundler-audit
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -164,7 +192,7 @@ dependencies:
164
192
  - - ">="
165
193
  - !ruby/object:Gem::Version
166
194
  version: '0'
167
- description:
195
+ description:
168
196
  email:
169
197
  - james@38degrees.org.uk
170
198
  executables: []
@@ -179,6 +207,7 @@ files:
179
207
  - app/assets/javascripts/darjeelink/sparkleh.js
180
208
  - app/assets/javascripts/darjeelink/tracking_link_generator.js
181
209
  - app/assets/stylesheets/darjeelink/application.css
210
+ - app/controllers/darjeelink/api_controller.rb
182
211
  - app/controllers/darjeelink/application_controller.rb
183
212
  - app/controllers/darjeelink/sessions_controller.rb
184
213
  - app/controllers/darjeelink/short_links_controller.rb
@@ -188,6 +217,7 @@ files:
188
217
  - app/importers/darjeelink/short_link_importer.rb
189
218
  - app/jobs/darjeelink/application_job.rb
190
219
  - app/mailers/darjeelink/application_mailer.rb
220
+ - app/models/darjeelink/api_token.rb
191
221
  - app/models/darjeelink/application_record.rb
192
222
  - app/models/darjeelink/short_link.rb
193
223
  - app/views/darjeelink/short_links/_short_link_form.erb
@@ -196,6 +226,7 @@ files:
196
226
  - app/views/darjeelink/short_links/new.html.erb
197
227
  - app/views/darjeelink/tracking_links/new.erb
198
228
  - app/views/layouts/darjeelink/application.html.erb
229
+ - config/brakeman.ignore
199
230
  - config/initializers/darjeelink.rb
200
231
  - config/initializers/omniauth.rb
201
232
  - config/initializers/rebrandly.rb
@@ -204,16 +235,17 @@ files:
204
235
  - db/migrate/20190304094710_case_insensitive_index_short_link_shortened_path.rb
205
236
  - db/migrate/20200505220716_rename_portkey_short_links_to_darjeelink_short_links.rb
206
237
  - db/migrate/20200505221026_rename_portkey_short_link_index.rb
238
+ - db/migrate/20210610083330_create_darjeelink_api_tokens.rb
207
239
  - lib/darjeelink.rb
208
240
  - lib/darjeelink/configuration.rb
209
241
  - lib/darjeelink/engine.rb
210
242
  - lib/darjeelink/version.rb
211
243
  - lib/tasks/darjeelink.rake
212
- homepage: https://github.com/38dgs/darjeelink
244
+ homepage: https://github.com/38degrees/darjeelink
213
245
  licenses:
214
246
  - MIT
215
247
  metadata: {}
216
- post_install_message:
248
+ post_install_message:
217
249
  rdoc_options: []
218
250
  require_paths:
219
251
  - lib
@@ -221,15 +253,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
221
253
  requirements:
222
254
  - - ">="
223
255
  - !ruby/object:Gem::Version
224
- version: '0'
256
+ version: '2.7'
225
257
  required_rubygems_version: !ruby/object:Gem::Requirement
226
258
  requirements:
227
259
  - - ">="
228
260
  - !ruby/object:Gem::Version
229
261
  version: '0'
230
262
  requirements: []
231
- rubygems_version: 3.0.8
232
- signing_key:
263
+ rubygems_version: 3.1.6
264
+ signing_key:
233
265
  specification_version: 4
234
266
  summary: URL Shortener
235
267
  test_files: []