Skip to content
This repository was archived by the owner on Sep 27, 2022. It is now read-only.

Add code ql #44

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#################################
# GitHub Dependabot Config info #
#################################
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10

# Maintain dependencies for docker
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10

# Maintain dependencies for python with pip
- package-ecosystem: "pip"
directory: "/dependencies"
schedule:
interval: "daily"
open-pull-requests-limit: 10
51 changes: 51 additions & 0 deletions .github/workflows/code-ql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: "Code Scanning - Action"

on:
push:
pull_request:
schedule:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: '30 1 * * 0'

jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
with:
languages: python

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below).
- name: Autobuild
uses: github/codeql-action/autobuild@v1

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following
# three lines and modify them (or add more) to build your code if your
# project uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
54 changes: 54 additions & 0 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Python application

on:
push:
branches-ignore: master

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout source code
uses: actions/checkout@v2

- name: Set up Python 3.5
uses: actions/setup-python@v2
with:
python-version: 3.5.4
# 3.5.2 was not found

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pipenv
# if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
pipenv install --clear --system

- name: Install pyenv and pyenv-virtualenv
run: |
brew update
brew install pyenv pyenv-virtualenv

- name: Pyenv install
run: |
pyenv install 3.5.4
pyenv virtualenv 3.5.4 productionready
pyenv local productionready
pyenv rehash

- name: Lint with Super-Linter
# uses: github/super-linter@v3
# env:
# VALIDATE_ALL_CODEBASE: false
# DEFAULT_BRANCH: master
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Would have run linting across code base and failed on errors"

- name: Test with pytest
run: |
pytest .
21 changes: 21 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Mark stale issues and pull requests

on:
schedule:
- cron: "30 1 * * *"

jobs:
stale:

runs-on: ubuntu-latest

steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Stale issue message'
stale-pr-message: 'Stale pull request message'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
days-before-stale: 5
days-before-close: 6
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
# ![Django DRF Example App](project-logo.png)

> ### Example Django DRF codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the [RealWorld](https://github.com/gothinkster/realworld-example-apps) API spec.
# Example Django DRF codebase containing real world examples (CRUD, auth,
# advanced patterns, etc) that adheres to the
# [RealWorld](https://github.com/gothinkster/realworld-example-apps) API
# spec.
>

<a href="https://thinkster.io/tutorials/django-json-api" target="_blank"><img width="454" src="https://raw.githubusercontent.com/gothinkster/realworld/master/media/learn-btn-hr.png" /></a>
<a href = "https://thinkster.io/tutorials/django-json-api" target = "_blank" > <img width = "454" src = "https://raw.githubusercontent.com/gothinkster/realworld/master/media/learn-btn-hr.png" / > < /a >

This repo is functionality complete — PR's and issues welcome!

## Installation
# Installation

1. Clone this repository: `git clone git@github.com:gothinkster/productionready-django-api.git`.
2. `cd` into `conduit-django`: `cd productionready-django-api`.
3. Install [pyenv](https://github.com/yyuu/pyenv#installation).
4. Install [pyenv-virtualenv](https://github.com/yyuu/pyenv-virtualenv#installation).
1. Clone this repository: `git clone git @ github.com: gothinkster / productionready - django - api.git`.
2. `cd` into `conduit - django`: `cd productionready - django - api`.
3. Install[pyenv](https: // github.com / yyuu / pyenv # installation).
4. Install[pyenv - virtualenv](https: // github.com / yyuu / pyenv - virtualenv # installation).
5. Install Python 3.5.2: `pyenv install 3.5.2`.
6. Create a new virtualenv called `productionready`: `pyenv virtualenv 3.5.2 productionready`.
7. Set the local virtualenv to `productionready`: `pyenv local productionready`.
8. Reload the `pyenv` environment: `pyenv rehash`.

If all went well then your command line prompt should now start with `(productionready)`.

If your command line prompt does not start with `(productionready)` at this point, try running `pyenv activate productionready` or `cd ../productionready-django-api`.
If your command line prompt does not start with `(productionready)` at this point, try running `pyenv activate productionready` or `cd .. / productionready - django - api`.

If pyenv is still not working, visit us in the Thinkster Slack channel so we can help you out.
1 change: 1 addition & 0 deletions conduit/apps/articles/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ class ArticlesAppConfig(AppConfig):
def ready(self):
import conduit.apps.articles.signals


default_app_config = 'conduit.apps.articles.ArticlesAppConfig'
8 changes: 5 additions & 3 deletions conduit/apps/articles/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Generated by Django 1.10 on 2016-08-28 15:43
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -18,14 +18,16 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Article',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('slug', models.SlugField(max_length=255, unique=True)),
('title', models.CharField(db_index=True, max_length=255)),
('description', models.TextField()),
('body', models.TextField()),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to='profiles.Profile')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
related_name='articles', to='profiles.Profile')),
],
options={
'abstract': False,
Expand Down
11 changes: 7 additions & 4 deletions conduit/apps/articles/migrations/0002_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Generated by Django 1.10 on 2016-08-28 16:00
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -17,12 +17,15 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Comment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('body', models.TextField()),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='articles.Article')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='profiles.Profile')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
related_name='comments', to='articles.Article')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
related_name='comments', to='profiles.Profile')),
],
options={
'ordering': ['-created_at', '-updated_at'],
Expand Down
6 changes: 4 additions & 2 deletions conduit/apps/articles/migrations/0003_auto_20160828_1656.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Tag',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('tag', models.CharField(max_length=255)),
Expand All @@ -29,6 +30,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='article',
name='tags',
field=models.ManyToManyField(related_name='articles', to='articles.Tag'),
field=models.ManyToManyField(
related_name='articles', to='articles.Tag'),
),
]
1 change: 1 addition & 0 deletions conduit/apps/articles/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from .models import Article


@receiver(pre_save, sender=Article)
def add_slug_to_article_if_not_exists(sender, instance, *args, **kwargs):
MAXIMUM_SLUG_LENGTH = 255
Expand Down
10 changes: 4 additions & 6 deletions conduit/apps/articles/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from django.conf.urls import include, url

from rest_framework.routers import DefaultRouter

from .views import (
ArticleViewSet, ArticlesFavoriteAPIView, ArticlesFeedAPIView,
CommentsListCreateAPIView, CommentsDestroyAPIView, TagListAPIView
)
from .views import (ArticlesFavoriteAPIView, ArticlesFeedAPIView,
ArticleViewSet, CommentsDestroyAPIView,
CommentsListCreateAPIView, TagListAPIView)

router = DefaultRouter(trailing_slash=False)
router.register(r'articles', ArticleViewSet)
Expand All @@ -18,7 +16,7 @@
url(r'^articles/(?P<article_slug>[-\w]+)/favorite/?$',
ArticlesFavoriteAPIView.as_view()),

url(r'^articles/(?P<article_slug>[-\w]+)/comments/?$',
url(r'^articles/(?P<article_slug>[-\w]+)/comments/?$',
CommentsListCreateAPIView.as_view()),

url(r'^articles/(?P<article_slug>[-\w]+)/comments/(?P<comment_pk>[\d]+)/?$',
Expand Down
16 changes: 7 additions & 9 deletions conduit/apps/articles/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from rest_framework import generics, mixins, status, viewsets
from rest_framework.exceptions import NotFound
from rest_framework.permissions import (
AllowAny, IsAuthenticated, IsAuthenticatedOrReadOnly
)
from rest_framework.permissions import (AllowAny, IsAuthenticated,
IsAuthenticatedOrReadOnly)
from rest_framework.response import Response
from rest_framework.views import APIView

Expand All @@ -11,7 +10,7 @@
from .serializers import ArticleSerializer, CommentSerializer, TagSerializer


class ArticleViewSet(mixins.CreateModelMixin,
class ArticleViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
Expand Down Expand Up @@ -49,7 +48,7 @@ def create(self, request):
serializer_data = request.data.get('article', {})

serializer = self.serializer_class(
data=serializer_data, context=serializer_context
data=serializer_data, context=serializer_context
)
serializer.is_valid(raise_exception=True)
serializer.save()
Expand Down Expand Up @@ -83,21 +82,20 @@ def retrieve(self, request, slug):

return Response(serializer.data, status=status.HTTP_200_OK)


def update(self, request, slug):
serializer_context = {'request': request}

try:
serializer_instance = self.queryset.get(slug=slug)
except Article.DoesNotExist:
raise NotFound('An article with this slug does not exist.')

serializer_data = request.data.get('article', {})

serializer = self.serializer_class(
serializer_instance,
serializer_instance,
context=serializer_context,
data=serializer_data,
data=serializer_data,
partial=True
)
serializer.is_valid(raise_exception=True)
Expand Down
1 change: 1 addition & 0 deletions conduit/apps/authentication/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AuthenticationAppConfig(AppConfig):
def ready(self):
import conduit.apps.authentication.signals


# This is how we register our custom app config with Django. Django is smart
# enough to look for the `default_app_config` property of each registered app
# and use the correct app config based on that value.
Expand Down
4 changes: 1 addition & 3 deletions conduit/apps/authentication/backends.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import jwt

from django.conf import settings

from rest_framework import authentication, exceptions

from .models import User
Expand Down Expand Up @@ -33,7 +31,7 @@ def authenticate(self, request):
request.user = None

# `auth_header` should be an array with two elements: 1) the name of
# the authentication header (in this case, "Token") and 2) the JWT
# the authentication header (in this case, "Token") and 2) the JWT
# that we should authenticate against.
auth_header = authentication.get_authorization_header(request).split()
auth_header_prefix = self.authentication_header_prefix.lower()
Expand Down
Loading