Compare commits
No commits in common. 'docs' and 'gh-pages' have entirely different histories.
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
# ignore mkdocs output/gh-pages branch |
||||
site/ |
||||
|
||||
# ignore secret branch |
||||
secret/ |
||||
|
||||
# ignore any makefiles |
||||
Makefile |
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
[submodule "mkdocs-material"] |
||||
path = mkdocs-material |
||||
url = https://git.charlesreid1.com/charlesreid1/mkdocs-material.git |
@ -1,13 +0,0 @@
@@ -1,13 +0,0 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE |
||||
Version 458.835.16.92, May 2018 |
||||
|
||||
Copyright (C) 2018 Charles Reid <charles@charlesreid1.com> |
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified |
||||
copies of this license document, and changing it is allowed as long |
||||
as the name is changed. |
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE |
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO. |
@ -1,58 +0,0 @@
@@ -1,58 +0,0 @@
|
||||
# github-heroku-attack-rabbits |
||||
|
||||
## What's this business all about, then? |
||||
|
||||
This repository helps you protect your secret pages by (deep breath): |
||||
|
||||
hosting your secret page of static and/or dynamic content using a free Heroku app |
||||
running a Python Flask server that uses Flask-Dance to authenticate visitors |
||||
with Github which allows you fine-grained access control over your pages based on |
||||
user attributes like organization or team membership or even things like how many |
||||
repositories a user has or how many vowels are in their username. |
||||
|
||||
Also, did I mention the attack rabbits? |
||||
|
||||
![warning: attack rabbits ahead](docs/img/warning.png) |
||||
|
||||
|
||||
## Where is everything? |
||||
|
||||
Final pages: |
||||
|
||||
* The finished product (pages on Heroku protected by attack rabbits) |
||||
is at [github-heroku-attack-rabbits.herokuapp.com](https://github-heroku-attack-rabbits.herokuapp.com) |
||||
|
||||
* The documentation is at [pages.charlesreid1.com/github-heroku-attack-rabbits](https://pages.charlesreid1.com/github-heroku-attack-rabbits) |
||||
|
||||
Two branches in this repo compose the github-heroku-attack-rabbits documentation: |
||||
|
||||
* (**YOU ARE HERE**) The [docs](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs) branch |
||||
contains the files needed to generate the |
||||
[github-heroku-attack-rabbits documentation site](https://pages.charlesreid1.com/github-heroku-attack-rabbits). |
||||
|
||||
* The [gh-pages](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/gh-pages) branch |
||||
contains the static files generated from the documentation. |
||||
The contents of this branch compose the |
||||
[github-heroku-attack-rabbits documentation site](https://pages.charlesreid1.com/github-heroku-attack-rabbits). |
||||
|
||||
Two branches illustrate github-heroku-attack-rabbits in practice: |
||||
|
||||
* The [secret](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/secret) branch contains the files needed to create the secret page. |
||||
This repository is public, so obviously these aren't *actually* secret, |
||||
but in practice this would be in a protected repository. |
||||
|
||||
* The [heroku-pages](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/heroku-pages) branch |
||||
contains the content that is actually pushed to Heroku - that is, |
||||
the final Flask app. |
||||
|
||||
|
||||
## Where do I start? |
||||
|
||||
See the [documentation](https://pages.charlesreid1.com/github-heroku-attack-rabbits) |
||||
or [docs/index.md](docs/index.md). |
||||
|
||||
|
||||
## License |
||||
|
||||
This is released under the [WTFPL](LICENSE). |
||||
|
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,i,n;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=(r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){var e,n,t,s=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],o=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new i;function l(){var e,r=c.limit-c.cursor;c.cursor>=n&&(e=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var r,i=c.cursor;return function(){var r,i=c.cursor+3;if(n=c.limit,0<=i&&i<=c.limit){for(e=i;;){if(r=c.cursor,c.in_grouping(d,97,248)){c.cursor=r;break}if(c.cursor=r,r>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(n=c.cursor)<e&&(n=e)}}(),c.limit_backward=i,c.cursor=c.limit,function(){var e,r;if(c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,t=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig")&&c.slice_del()),c.cursor=c.limit-t,c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from("løs")}}(),c.cursor=c.limit,c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,t=c.slice_to(t),c.limit_backward=r,c.eq_v_b(t)&&c.slice_del()):c.limit_backward=r),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.jp=function(){this.pipeline.reset(),this.pipeline.add(e.jp.stopWordFilter,e.jp.stemmer),r?this.tokenizer=e.jp.tokenizer:(e.tokenizer&&(e.tokenizer=e.jp.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.jp.tokenizer))};var t=new e.TinySegmenter;e.jp.tokenizer=function(n){if(!arguments.length||null==n||null==n)return[];if(Array.isArray(n))return n.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(var i=n.toString().toLowerCase().replace(/^\s+/,""),o=i.length-1;o>=0;o--)if(/\S/.test(i.charAt(o))){i=i.substring(0,o+1);break}return t.segment(i).filter(function(e){return!!e}).map(function(t){return r?new e.Token(t):t})},e.jp.stemmer=function(e){return e},e.Pipeline.registerFunction(e.jp.stemmer,"stemmer-jp"),e.jp.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",e.jp.stopWordFilter=function(t){if(-1===e.jp.stopWordFilter.stopWords.indexOf(r?t.toString():t))return t},e.jp.stopWordFilter=e.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),e.Pipeline.registerFunction(e.jp.stopWordFilter,"stopWordFilter-jp")}}); |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var i=Array.prototype.slice.call(arguments),t=i.join("-"),r="",n=[],s=[],p=0;p<i.length;++p)"en"==i[p]?(r+="\\w",n.unshift(e.stopWordFilter),n.push(e.stemmer),s.push(e.stemmer)):(r+=e[i[p]].wordCharacters,n.unshift(e[i[p]].stopWordFilter),n.push(e[i[p]].stemmer),s.push(e[i[p]].stemmer));var o=e.trimmerSupport.generateTrimmer(r);return e.Pipeline.registerFunction(o,"lunr-multi-trimmer-"+t),n.unshift(o),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,n),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,s))}}}}); |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,i;e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){var e,i,t=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],o=[new r("dt",-1,-1),new r("vt",-1,-1)],s=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],a=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],m=[119,125,149,1],l=new n;this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var r,n,u,d,c=l.cursor;return function(){var r,n=l.cursor+3;if(i=l.limit,0<=n||n<=l.limit){for(e=n;;){if(r=l.cursor,l.in_grouping(a,97,248)){l.cursor=r;break}if(r>=l.limit)return;l.cursor=r+1}for(;!l.out_grouping(a,97,248);){if(l.cursor>=l.limit)return;l.cursor++}(i=l.cursor)<e&&(i=e)}}(),l.limit_backward=c,l.cursor=l.limit,function(){var e,r,n;if(l.cursor>=i&&(r=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,e=l.find_among_b(t,29),l.limit_backward=r,e))switch(l.bra=l.cursor,e){case 1:l.slice_del();break;case 2:n=l.limit-l.cursor,l.in_grouping_b(m,98,122)?l.slice_del():(l.cursor=l.limit-n,l.eq_s_b(1,"k")&&l.out_grouping_b(a,97,248)&&l.slice_del());break;case 3:l.slice_from("er")}}(),l.cursor=l.limit,n=l.limit-l.cursor,l.cursor>=i&&(r=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,l.find_among_b(o,2)?(l.bra=l.cursor,l.limit_backward=r,l.cursor=l.limit-n,l.cursor>l.limit_backward&&(l.cursor--,l.bra=l.cursor,l.slice_del())):l.limit_backward=r),l.cursor=l.limit,l.cursor>=i&&(d=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,(u=l.find_among_b(s,11))?(l.bra=l.cursor,l.limit_backward=d,1==u&&l.slice_del()):l.limit_backward=d),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&""!=r||!t&&0!=t||!i)throw"Bad Among initialisation: s:"+r+", substring_i: "+t+", result: "+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var r;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(t){r=t,this.cursor=0,this.limit=t.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var t=r;return r=null,t},in_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e<=s&&e>=i&&t[(e-=i)>>3]&1<<(7&e))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&t[(e-=i)>>3]&1<<(7&e))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e>s||e<i)return this.cursor++,!0;if(!(t[(e-=i)>>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e<i)return this.cursor--,!0;if(!(t[(e-=i)>>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor+s)!=i.charCodeAt(s))return!1;return this.cursor+=t,!0},eq_s_b:function(t,i){if(this.cursor-this.limit_backward<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor-t+s)!=i.charCodeAt(s))return!1;return this.cursor-=t,!0},find_among:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=l;m<_.s_size;m++){if(n+l==u){f=-1;break}if(f=r.charCodeAt(n+l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){if(o>=(_=t[s]).s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=(m=t[a]).s_size-1-l;_>=0;_--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-m.s[_])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var m;if(o>=(m=t[s]).s_size){if(this.cursor=n-m.s_size,!m.method)return m.result;var b=m.method();if(this.cursor=n-m.s_size,b)return m.result}if((s=m.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,t;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){var e,t,i=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],s=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new n;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var r,n=m.cursor;return function(){var r,n=m.cursor+3;if(t=m.limit,0<=n||n<=m.limit){for(e=n;;){if(r=m.cursor,m.in_grouping(o,97,246)){m.cursor=r;break}if(m.cursor=r,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)<e&&(t=e)}}(),m.limit_backward=n,m.cursor=m.limit,function(){var e,r=m.limit_backward;if(m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,r=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=r),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from("lös");break;case 3:m.slice_from("full")}m.limit_backward=r}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); |
@ -0,0 +1,542 @@
@@ -0,0 +1,542 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/custom_domains/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Custom Domains - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#custom-domains" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Custom Domains |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<a href="./" title="Custom Domains" class="md-nav__link md-nav__link--active"> |
||||
Custom Domains |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="custom-domains">Custom Domains</h1> |
||||
<p>If you want to use a custom domain:</p> |
||||
<ul> |
||||
<li>Set up custom domain using Heroku command line interface</li> |
||||
<li>This will set up a DNS subdomain specifically for your app</li> |
||||
<li>Point your DNS records to the Heroku DNS subdomain</li> |
||||
</ul> |
||||
<p>This also introduces complications with HTTP vs HTTPS: |
||||
OAuth must happen over HTTPS (required by protocol). |
||||
But you the user can control your domain and create |
||||
SSL certificates for it, but Heroku is hosting the app.</p> |
||||
<p>You have two options: the free option, and the pay option.</p> |
||||
<p><strong>The pay option:</strong> For $7/mo you can upgrade to hobby nodes, |
||||
which allows you to give Heroku permission to create an SSL |
||||
certificate for your domain. This is the easiest solution |
||||
and requires zero setup, zero certificate management.</p> |
||||
<p><strong>The free option:</strong> You can have your domain (HTTP only) |
||||
forward to Heroku (HTTPS can't be forwarded - that's <strong><em>key</em></strong>). |
||||
When you hit the Heroku domain, it will log the user in to Github. |
||||
When the user logs in successfully, Github will redirect them to |
||||
the callback URL. This callback URL <strong><em>MUST</em></strong> be HTTPS, so it cannot |
||||
redirect back to your (HTTP-only) custom domain.</p> |
||||
<p>That means the userr will, after authenticating with Github, |
||||
always be redirected to <code>https://my-cool-app.herokuapp.com</code> |
||||
and never <code>http://my-cool-custom-domain-that-cannot-be-used-as-a-callback-because-it-is-https-only.com</code>.</p> |
||||
<p>The paid option is much, much simpler in the end |
||||
and will save you $7/mo in setup time alone.</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Deploying Flask App to Heroku |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
# Custom Domains |
||||
|
||||
If you want to use a custom domain: |
||||
|
||||
* Set up custom domain using Heroku command line interface |
||||
* This will set up a DNS subdomain specifically for your app |
||||
* Point your DNS records to the Heroku DNS subdomain |
||||
|
||||
This also introduces complications with HTTP vs HTTPS: |
||||
OAuth must happen over HTTPS (required by protocol). |
||||
But you the user can control your domain and create |
||||
SSL certificates for it, but Heroku is hosting the app. |
||||
|
||||
You have two options: the free option, and the pay option. |
||||
|
||||
**The pay option:** For $7/mo you can upgrade to hobby nodes, |
||||
which allows you to give Heroku permission to create an SSL |
||||
certificate for your domain. This is the easiest solution |
||||
and requires zero setup, zero certificate management. |
||||
|
||||
**The free option:** You can have your domain (HTTP only) |
||||
forward to Heroku (HTTPS can't be forwarded - that's ***key***). |
||||
When you hit the Heroku domain, it will log the user in to Github. |
||||
When the user logs in successfully, Github will redirect them to |
||||
the callback URL. This callback URL ***MUST*** be HTTPS, so it cannot |
||||
redirect back to your (HTTP-only) custom domain. |
||||
|
||||
That means the userr will, after authenticating with Github, |
||||
always be redirected to `https://my-cool-app.herokuapp.com` |
||||
and never `http://my-cool-custom-domain-that-cannot-be-used-as-a-callback-because-it-is-https-only.com`. |
||||
|
||||
The paid option is much, much simpler in the end |
||||
and will save you $7/mo in setup time alone. |
@ -1,174 +0,0 @@
@@ -1,174 +0,0 @@
|
||||
# Create a Flask App using Flask-Dance |
||||
|
||||
This is the heart of the method. |
||||
|
||||
The best thing to do here is just to walk you through the script. |
||||
|
||||
Import statements: |
||||
|
||||
``` |
||||
import os, json |
||||
from os.path import join, isfile, isdir |
||||
from werkzeug.contrib.fixers import ProxyFix |
||||
from flask import Flask, redirect, url_for, send_from_directory |
||||
from flask_dance.contrib.github import make_github_blueprint, github |
||||
``` |
||||
|
||||
Note that flask-dance adds an OAuth login/callback route |
||||
to your Flask app by creating a `/login` blueprint, |
||||
meaning all the OAuth stuff is just magically available |
||||
via `/login`. |
||||
|
||||
Set paths for static content: |
||||
|
||||
``` |
||||
PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__)) |
||||
STATIC_PATH = 'content' |
||||
``` |
||||
|
||||
Create and configure app. This requires confidential information |
||||
for the Github application you created, specifically the client |
||||
ID and client secret. These are at the very top of the page when |
||||
you visit your app's settings page. |
||||
|
||||
To find this, after you log in, click your profile photo in the |
||||
upper right > Settings > Developer Settings > OAuth Apps > click the |
||||
name for your OAuth app. |
||||
|
||||
``` |
||||
app = Flask(__name__) |
||||
|
||||
# this worked locally, but not on heroku |
||||
app.wsgi_app = ProxyFix(app.wsgi_app) |
||||
|
||||
app.secret_key = os.environ.get("FLASK_SECRET_KEY", "9502861d41e8729c5cae3225920b1b46") |
||||
|
||||
app.config["RESULT_STATIC_PATH"] = STATIC_PATH #os.path.join(PROJECT_ROOT,STATIC_PATH) |
||||
app.config["GITHUB_OAUTH_CLIENT_ID"] = os.environ.get("GITHUB_OAUTH_CLIENT_ID") |
||||
app.config["GITHUB_OAUTH_CLIENT_SECRET"] = os.environ.get("GITHUB_OAUTH_CLIENT_SECRET") |
||||
``` |
||||
|
||||
Now the magic happens: we use flask-dance to create a blueprint |
||||
that has methods and settings all ready to go for us to do the |
||||
OAuth dance. |
||||
|
||||
`make_github_blueprint()` is part of the contrib module of flask-dance. |
||||
There are several similar methods to generate blueprints for |
||||
authenticating with other APIs. |
||||
|
||||
``` |
||||
github_bp = make_github_blueprint( |
||||
client_id = os.environ.get('GITHUB_OAUTH_CLIENT_ID'), |
||||
client_secret = os.environ.get('GITHUB_OAUTH_CLIENT_SECRET'), |
||||
scope='read:org') |
||||
|
||||
app.register_blueprint(github_bp, url_prefix="/login") |
||||
|
||||
contents404 = "<html><body><h1>Status: Error 404 Page Not Found</h1></body></html>" |
||||
contents403 = "<html><body><h1>Status: Error 403 Access Denied</h1></body></html>" |
||||
contents200 = "<html><body><h1>Status: OK 200</h1></body></html>" |
||||
``` |
||||
|
||||
Deal with the `/` route first: |
||||
|
||||
* Check if authorized, if not, redirect them to the login URL |
||||
(magical URLs taken care of magically by our `make_github_blueprint` |
||||
function above) |
||||
* If user is authorized (i.e., if they have gone through the OAuth |
||||
process and given their passsword to Github and been redirected |
||||
to your app with an OAuth token), then the next step is to |
||||
find out some information about them. |
||||
* Use the `github` object to call the Github API directly. |
||||
* Decide what to do from there. |
||||
|
||||
``` |
||||
@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user/orgs") |
||||
if resp.ok: |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']=='rainbow-mind-machine': |
||||
``` |
||||
|
||||
The next line is important to how the server works: |
||||
if all of the criteria above have been met, we return |
||||
a static file: |
||||
|
||||
``` |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
``` |
||||
|
||||
This is normally "bad practice," and numerous type A people |
||||
on the internet will tell you Flask should not be used for |
||||
serving static files, and that you should use nginx etc., |
||||
but these fail to igonore the following: |
||||
|
||||
* Heroku does not let you run or configure nginx |
||||
* For crying out loud this example is about attack rabbits |
||||
stop taking everything so seriously |
||||
|
||||
Now that we've got that out of the way... |
||||
|
||||
Here's how we serve up static files. This is a total hack, |
||||
but it works. It takes any arbitrary path supplied by the |
||||
user, and attempts to find a corresponding file to serve up |
||||
on disk. |
||||
|
||||
If the user passes a file, then that file is served up. |
||||
|
||||
If the user passes a directory, then `index.html` is served up. |
||||
|
||||
If the user asks for a non-existent file, a 404 error is shown. |
||||
|
||||
If the user is not allowed to view the content, they will face |
||||
the bowel-emptying terrors of the 403 error. |
||||
|
||||
``` |
||||
@app.route('/<path:path>') |
||||
def catch_all(path): |
||||
|
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
username = github.get("/user").json()['login'] |
||||
|
||||
rsp = app.config["RESULT_STATIC_PATH"] |
||||
resp = github.get("/user/orgs") |
||||
if resp.ok: |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']=='dcppc': |
||||
|
||||
if(path==''): |
||||
return send_from_directory(rsp, 'index.html') |
||||
|
||||
elif(isdir(join(rsp,path))): |
||||
return send_from_directory(join(rsp,path),'index.html') |
||||
|
||||
elif(isfile(join(rsp,path))): |
||||
return send_from_directory(rsp, path) |
||||
|
||||
else: |
||||
return contents404 |
||||
|
||||
return contents403 |
||||
``` |
||||
|
||||
Last, set a default 404 handler, and run the app: |
||||
|
||||
``` |
||||
@app.errorhandler(404) |
||||
def oops(e): |
||||
return contents404 |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
app.run() |
||||
``` |
||||
|
@ -1,25 +0,0 @@
@@ -1,25 +0,0 @@
|
||||
# Authenticate Users on Github Membership |
||||
|
||||
For the sake of simplicity, will just demonstrate how this |
||||
works for a single route, but you can combine different |
||||
rules into multiple routes to provide access to different |
||||
people on different parts of a site. |
||||
|
||||
Here is the relevant method that serves up `index.html` |
||||
if the user is authenticated: |
||||
|
||||
``` |
||||
@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user") |
||||
|
||||
if resp.ok: |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
|
||||
return contents403 |
||||
``` |
||||
|
||||
|
@ -1,22 +0,0 @@
@@ -1,22 +0,0 @@
|
||||
# Authenticate Users on Organization or Team Membership |
||||
|
||||
Here is how we can make access to a given page or route |
||||
conditional on membership in an organization (in this |
||||
example, membership in the `rainbow-mind-machine` organization |
||||
is required for access): |
||||
|
||||
``` |
||||
@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user/orgs") |
||||
if resp.ok: |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']=='rainbow-mind-machine': |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
``` |
||||
|
@ -1,27 +0,0 @@
@@ -1,27 +0,0 @@
|
||||
# Authenticate Users on Other Criteria |
||||
|
||||
Suppose we wanted to do something silly like restrict |
||||
access to a page to users with Github handles that were |
||||
between 5 and 7 letters. |
||||
|
||||
Here is the relevant method that serves up `index.html` |
||||
if the user's Github handle is 5-7 letters long: |
||||
|
||||
``` |
||||
@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user") |
||||
|
||||
if resp.ok: |
||||
username = resp.json()['login'] |
||||
if len(username)>=5 and len(username)<=7: |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
|
||||
return contents403 |
||||
``` |
||||
|
||||
|
||||
|
@ -1,64 +0,0 @@
@@ -1,64 +0,0 @@
|
||||
# Authenticate Different Users on Different Portions of Site |
||||
|
||||
**NOTE: if you are authenticating using membership on a team, you will need the |
||||
team id of the team you are interested in authenticating against.** |
||||
|
||||
For this example, let's expand the routes we're looking at |
||||
a bit more. |
||||
|
||||
Suppose we have two folders, `team_only` and `org_only`. |
||||
|
||||
The `team_only` folder should only be accessible to your team, `Team Gold`. |
||||
|
||||
The `org_only` folder should only be accessible to your organization, `Colorful Colors`. |
||||
|
||||
The main site (i.e., all other files) should be publicly accessible. |
||||
|
||||
``` |
||||
@app.route('/') |
||||
def index(): |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
|
||||
|
||||
@app.route('/team_only/<path:path>') |
||||
def team_gold(path): |
||||
|
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
rsp = app.config["RESULT_STATIC_PATH"] |
||||
|
||||
resp = github.get("/user") |
||||
if resp.ok: |
||||
username = resp.json()['login'] |
||||
|
||||
team_id = 'XXXXX' |
||||
|
||||
resp = github.get("/teams/%s/members/%s"%( team_id, username )) |
||||
if resp.code==204: |
||||
team_gold_dir = os.path.join(STATIC_PATH, 'team_only') |
||||
return send_from_directory(team_gold_dir, 'index.html') |
||||
return contents403 |
||||
|
||||
|
||||
@app.route('/org_only/<path:path>') |
||||
def team_gold(path): |
||||
|
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
rsp = app.config["RESULT_STATIC_PATH"] |
||||
|
||||
resp = github.get("/user") |
||||
if resp.ok: |
||||
|
||||
my_org = 'XXXXXXXX' |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']==my_org: |
||||
color_org_dir = os.path.join(STATIC_PATH, 'org_only') |
||||
return send_from_directory(color_org_dir, 'index.html') |
||||
return contents403 |
||||
``` |
||||
|
@ -1,98 +0,0 @@
@@ -1,98 +0,0 @@
|
||||
# Deploying to Heroku |
||||
|
||||
Once we have debugged the Flask app and we are happy with it, |
||||
we are ready to deploy it to Heroku. |
||||
|
||||
|
||||
## Repository Setup |
||||
|
||||
To do this, you should set up your repo as follows: |
||||
|
||||
Clone the repo: |
||||
|
||||
``` |
||||
$ git clone https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git |
||||
``` |
||||
|
||||
The repo has the following structure: |
||||
|
||||
``` |
||||
github-heroku-attack-rabbits/ |
||||
LICENSE |
||||
README.md |
||||
mkdocs.yml |
||||
docs/ |
||||
index.md |
||||
... |
||||
mkdocs-material/ |
||||
... |
||||
``` |
||||
|
||||
Now, inside the repo, clone the repo again, |
||||
but this time clone the `heroku-pages` branch |
||||
to the `site/` directory: |
||||
|
||||
``` |
||||
$ cd github-heroku-attack-rabbits/ |
||||
$ git clone -b heroku-pages https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git site |
||||
``` |
||||
|
||||
|
||||
## Heroku Deploy Process |
||||
|
||||
To deploy content to Heroku, we add our Heroku project as a git remote |
||||
(see the [heroku](heroku.md) page for how to do that) and then push to |
||||
to the master branch of the heroku remote git repo. Changes are pulled |
||||
in by Heroku and the app is restarted each time you run `git push`. |
||||
|
||||
We walk through the steps below. |
||||
|
||||
|
||||
## Heroku Login |
||||
|
||||
From the `site/` directory containing the contents of the `heroku-pages` branch, |
||||
that is, containing the Python flask app, log in to Heroku: |
||||
|
||||
``` |
||||
$ heroku login |
||||
``` |
||||
|
||||
|
||||
## Add Heroku Remote to `heroku-pages` Branch |
||||
|
||||
Now have Heroku add the proper git remote address: |
||||
|
||||
``` |
||||
$ heroku git:remote -a <heroku-app-name> |
||||
``` |
||||
|
||||
Now you're ready to deploy to Heroku. |
||||
|
||||
|
||||
## Deploy to Heroku |
||||
|
||||
Double check your app is ready, then deploy: |
||||
|
||||
``` |
||||
$ git push heroku heroku-pages:master |
||||
``` |
||||
|
||||
This will push the local branch `heroku-pages` to |
||||
the remote branch `master` on the `heroku` remote. |
||||
This should begin a pre-commit hook where Heroku |
||||
compiles your Python app. You should get the green |
||||
light, if you tested your app locally and everything |
||||
was good to go. |
||||
|
||||
|
||||
## Check Your Heroku App |
||||
|
||||
Your Heroku app will be available at |
||||
|
||||
``` |
||||
https://<heroku-app-name>.herokuapp.com |
||||
``` |
||||
|
||||
You should see your Python flask app |
||||
show up shortly. |
||||
|
@ -1,42 +0,0 @@
@@ -1,42 +0,0 @@
|
||||
# Testing Flask App Locally |
||||
|
||||
We set up the Github App to use a callback of `https://localhost:5000/login/github/authorized` |
||||
so that we could test the app locally. Now it is time to test the app locally. |
||||
|
||||
The application needs access to your Github app id and token. Those are provided |
||||
via the `GITHUB_OAUTH_CLIENT_{ID,SECRET}` environment variables. Set these |
||||
when you run the actual python command to run the server: |
||||
|
||||
``` |
||||
$ GITHUB_OAUTH_CLIENT_ID="xxxxxxx" \ |
||||
GITHUB_OAUTH_CLIENT_SECRET="xxxxxxx" \ |
||||
OAUTHLIB_INSECURE_TRANSPORT=true \ |
||||
python github.py |
||||
``` |
||||
|
||||
This runs the Flask server on port 5000, where it will wait for a visitor. |
||||
The way we have our application written in this example, the main `/` route |
||||
will redirect the user to a Github login screen immediately, but you could |
||||
also present the user with a friendly welcome page when they go to `/`, |
||||
and only redirect them to the Github login prompt when they visit a |
||||
URL like `/login` or `/auth`. |
||||
|
||||
Once you run the above command, open the following URL in your browser: |
||||
|
||||
``` |
||||
http://localhost:5000/ |
||||
``` |
||||
|
||||
**NOTE: Make sure you are logged out of Github and that you clear your cookies |
||||
if you are already logged in as one user and wish to authenticate as another. |
||||
The login is _very_ persistent so you may need to close and re-open your browser.** |
||||
|
||||
Visiting the address above will result in your being redirected to a Github |
||||
login page. Once you login, Github will redirect the user back to the |
||||
github-heroku-attack-rabbits application with a token that the application |
||||
can use to perform actions on behalf of the user. |
||||
|
||||
## Next Step? |
||||
|
||||
If the app works, the next step is to deploy to Heroku. |
||||
|
@ -1,57 +0,0 @@
@@ -1,57 +0,0 @@
|
||||
## get started with github |
||||
|
||||
We mentioned on the [heroku](heroku.md) page that heroku |
||||
creates a remote git repository to hold the files you |
||||
want to host. |
||||
|
||||
To use the contents of a Github repository on Heroku, |
||||
just treat it like another git remote, no special setup |
||||
is needed. |
||||
|
||||
However, to set up your Github-Heroku attack rabbits to |
||||
authenticate a user via Github, and mercilessly attack |
||||
all intruders, you must create a Github OAuth App. |
||||
|
||||
### Creating Github OAuth App |
||||
|
||||
Log into Github |
||||
|
||||
Go to Settings |
||||
|
||||
Click "Developer Settings" on the left side |
||||
|
||||
Click "New OAuth App" button in upper right |
||||
|
||||
**What do these settings mean?** |
||||
|
||||
* **Application name** is what will be shown to users when they visit |
||||
a page protected by the attack rabbits and are prompted for |
||||
their password by Github. |
||||
|
||||
* **Homepage URL/Application description** are for users who want to know more |
||||
about your killer attack rabbit Github app |
||||
|
||||
* **Authorization callback URL** is the URL that the users will be sent to |
||||
once they authenticate with Github and they are granted an OAuth token. |
||||
This is the magic ingredient that allows you to take actions on behalf |
||||
of the account logging in. |
||||
|
||||
In this guide we'll cover the case of checking membership in organizations or teams, |
||||
but what your attack rabbits end up doing to determine if a user is allowed to |
||||
access your secret pages is up to you. |
||||
|
||||
## Values to use |
||||
|
||||
You should set your own values for the **name** and **description** fields. |
||||
|
||||
The **home URL** is not actually necessary - it is simply provided for users to |
||||
get more information about your app. |
||||
|
||||
The most important is the **callback URL**, which should be set to: |
||||
|
||||
http://localhost:5000/login/github/authorized |
||||
|
||||
This is for testing locally *only*. |
||||
|
||||
Don't use HTTPS in the callback URL! |
||||
|
@ -1,67 +0,0 @@
@@ -1,67 +0,0 @@
|
||||
# create heroku app |
||||
|
||||
|
||||
### Heroku toolbelt |
||||
|
||||
Heroku offers a really nice command line interface tool called |
||||
Heroku Toolbelt. It is available through Homebrew and Aptitude: |
||||
|
||||
``` |
||||
$ brew install heroku # from Mac |
||||
|
||||
$ apt-get install heroku # from Ubuntu |
||||
``` |
||||
|
||||
It is then available on the command line as `heroku`. |
||||
|
||||
The first thing you should do is authenticate with |
||||
your Heroku account by running |
||||
|
||||
``` |
||||
$ heroku login |
||||
``` |
||||
|
||||
We will use this command line application for the following tasks: |
||||
|
||||
* Create a git remote to point to the right Heroku git remote location |
||||
* Set environment variables (for e.g. secret keys) on the remote Heroku instance |
||||
* Get information (logs, status, etc.) about your Heroku app |
||||
|
||||
We will cover these commands as they come up. |
||||
|
||||
|
||||
### Create heroku app |
||||
|
||||
Start by creating a heroku app. |
||||
|
||||
* Each heroku app must have a unique name |
||||
* Each heroku app creates a remote git repo |
||||
* Master branch is what Heroku deploys publicly on herokuapps.com |
||||
* You will also need heroku CLI to link your github repo to your heroku app |
||||
|
||||
|
||||
### Where heroku app lives |
||||
|
||||
Suppose you are creating an app called `my-cool-app` |
||||
on heroku. Then your application will be hosted by |
||||
Heroku and will be available at the URL: |
||||
|
||||
``` |
||||
https://my-cool-app.herokuapp.com |
||||
``` |
||||
|
||||
### How heroku apps works |
||||
|
||||
If you have used Github Pages before, Heroku uses a similar |
||||
model (live hosting one particular branch of a git repository). |
||||
However, Heroku is different because you can run dynamic scripts |
||||
using Python, Ruby, PHP, etc. |
||||
|
||||
To change the content of your Heroku app, just change the contents |
||||
of the repository, and push to master (push to the master branch of |
||||
the remote Heroku repository). |
||||
|
||||
You will need to structure your repository carefully. |
||||
That's what this page is here to help you do. |
||||
Heroku can figure out the rest from there. |
||||
|
@ -1,92 +0,0 @@
@@ -1,92 +0,0 @@
|
||||
# github-heroku-attack-rabbits |
||||
|
||||
## What's this business all about, then? |
||||
|
||||
This repository helps you put access control into place to protect your secret pages by (deep breath): |
||||
|
||||
hosting your secret page of static and/or dynamic content by using a free Heroku app |
||||
running a Python Flask server that uses Flask-Dance to authenticate visitors |
||||
with Github using OAuth which allows you fine-grained access control for your pages |
||||
using user attributes like organization or team membership or even things like how many |
||||
vowels a user has in their username. |
||||
|
||||
Also, did I mention the attack rabbits? |
||||
|
||||
![warning: attack rabbits ahead](img/warning.png) |
||||
|
||||
|
||||
## Where is everything? |
||||
|
||||
Final pages: |
||||
|
||||
* The finished product (pages on Heroku protected by attack rabbits) |
||||
is at [github-heroku-attack-rabbits.herokuapp.com](https://github-heroku-attack-rabbits.herokuapp.com) |
||||
|
||||
* The documentation is at [pages.charlesreid1.com/github-heroku-attack-rabbits](https://pages.charlesreid1.com/github-heroku-attack-rabbits) |
||||
|
||||
Two branches in this repo compose the github-heroku-attack-rabbits documentation: |
||||
|
||||
* (**YOU ARE HERE**) The [docs](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs) branch |
||||
contains the files needed to generate the |
||||
[github-heroku-attack-rabbits documentation site](https://pages.charlesreid1.com/github-heroku-attack-rabbits). |
||||
|
||||
* The [gh-pages](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/gh-pages) branch |
||||
contains the static files generated from the documentation. |
||||
The contents of this branch compose the |
||||
[github-heroku-attack-rabbits documentation site](https://pages.charlesreid1.com/github-heroku-attack-rabbits). |
||||
|
||||
Two branches illustrate github-heroku-attack-rabbits in practice: |
||||
|
||||
* The [secret](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/secret) branch contains the files needed to create the secret page. |
||||
This repository is public, so obviously these aren't *actually* secret, |
||||
but in practice this would be in a protected repository. |
||||
|
||||
* The [heroku-pages](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/heroku-pages) branch |
||||
contains the content that is actually pushed to Heroku - that is, |
||||
the final Flask app. |
||||
|
||||
|
||||
## Contents |
||||
|
||||
An overview of the steps: |
||||
|
||||
[Get Started with Heroku](heroku.md) |
||||
|
||||
[Get Started with Github](github.md) |
||||
|
||||
[Initialize Repository: Branches](repo.md) |
||||
|
||||
[Create a Flask App using Flask-Dance](flask.md) |
||||
|
||||
* [Authenticate users based on Github membership only](flask_auth_github.md) |
||||
* [Authenticate users based on organization or team membership](flask_auth_org.md) |
||||
* [Authenticate users based on some other criteria](flask_auth_other.md) |
||||
* [Protection portions of the site](flask_auth_portions.md) |
||||
|
||||
[Test Flask App Locally](flask_local.md) |
||||
|
||||
[Deploying Flask App to Heroku](flask_heroku.md) |
||||
|
||||
[Custom Domains](custom_domains.md) |
||||
|
||||
|
||||
## Links |
||||
|
||||
Python software used: |
||||
|
||||
* [Flask](http://flask.pocoo.org/) |
||||
* [Flask-dance](https://github.com/singingwolfboy/flask-dance) |
||||
* [Flask-dance-github](https://github.com/singingwolfboy/flask-dance-github) |
||||
* [mkdocs-material (documentation theme)](https://github.com/squidfunk/mkdocs-material) |
||||
* [mkdocs (documentation)](http://www.mkdocs.org/) |
||||
|
||||
Commercial services: |
||||
|
||||
* [Heroku](https://heroku.com) |
||||
* [Github](https://github.com) |
||||
|
||||
|
||||
## License |
||||
|
||||
This is released under the [WTFPL](https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE). |
||||
|
@ -1,110 +0,0 @@
@@ -1,110 +0,0 @@
|
||||
# Initialize Git Repository |
||||
|
||||
Let's talk through how a repository should be laid out |
||||
if we're going to be hosting a Flask app on Heroku. |
||||
|
||||
## Branches |
||||
|
||||
We will need a minimum of two branches. Here we specify |
||||
the names that these branches will have in your Github repo, |
||||
**which is different from the names of the branches on Heroku**: |
||||
|
||||
Branches on Github: |
||||
|
||||
* `heroku-pages` - this branch contains the content that Heroku will host. |
||||
Specifically, it contains the Flask application in a `.py` file, |
||||
and a few other files to help Heroku determine how to run the app |
||||
and what to install. |
||||
|
||||
* `master` - this branch contains the content used to generate the documentation |
||||
and page content that is being hosted behind the Heroku attack sheep. |
||||
The documentation you are reading right now is from the master branch, |
||||
and was made with `mkdocs`. |
||||
|
||||
On Heroku, we only have a single branch: |
||||
|
||||
* `master` (Heroku) maps to `heroku-pages` (Github) |
||||
|
||||
## Repo Layout |
||||
|
||||
Let's talk about the layout of the repository. |
||||
|
||||
If you wish to build the site in order to deploy it to Heroku, |
||||
you should clone the `master` branch (preparing to make the |
||||
content for your attack sheep-protected page): |
||||
|
||||
``` |
||||
$ git clone -b master https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git |
||||
$ cd github-heroku-attack-rabbits |
||||
``` |
||||
|
||||
Once you are *inside* the master branch, clone the repo again, |
||||
but this time clone the `heroku-pages` branch, and clone it |
||||
to the `site/` folder: |
||||
|
||||
``` |
||||
$ git clone -b heroku-pages https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git site |
||||
$ cd site |
||||
``` |
||||
|
||||
Now you will want to set up the Heroku remote: |
||||
|
||||
``` |
||||
$ heroku git:remote -a my-cool-project |
||||
``` |
||||
|
||||
The layout should now be: |
||||
|
||||
``` |
||||
my-cool-project-repo/ <-- my-cool-project repo pointing to master branch |
||||
|
||||
docs/ \ |
||||
index.md | |
||||
heroku.md | <-- mkdocs files |
||||
... | (can use any static content generator: |
||||
| pelican, sphinx, etc.) |
||||
mkdocs.yml / |
||||
|
||||
site/ <-- my-cool-project repo pointing to heroku-pages branch |
||||
|
||||
Procfile \ |
||||
github.py | <-- heroku python app files |
||||
requirements.txt | (can also use ruby, php, js, etc.) |
||||
runtime.txt | (can also use ruby, php, js, etc.) |
||||
... / |
||||
|
||||
content/ \ |
||||
index.html | <-- static content hosted by Flask |
||||
sitemap.xml | |
||||
... / |
||||
``` |
||||
|
||||
|
||||
## Workflow |
||||
|
||||
Once you have things set up according to the instructions and diagram above, |
||||
you're ready to run the push-to-deploy workflow and start running your secret |
||||
site on Heroku. |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,676 @@
@@ -0,0 +1,676 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Create a Flask App using Flask-Dance - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#create-a-flask-app-using-flask-dance" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Create a Flask App using Flask-Dance |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<a href="./" title="Create a Flask App using Flask-Dance" class="md-nav__link md-nav__link--active"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="create-a-flask-app-using-flask-dance">Create a Flask App using Flask-Dance</h1> |
||||
<p>This is the heart of the method.</p> |
||||
<p>The best thing to do here is just to walk you through the script.</p> |
||||
<p>Import statements:</p> |
||||
<pre><code class="python">import os, json |
||||
from os.path import join, isfile, isdir |
||||
from werkzeug.contrib.fixers import ProxyFix |
||||
from flask import Flask, redirect, url_for, send_from_directory |
||||
from flask_dance.contrib.github import make_github_blueprint, github |
||||
</code></pre> |
||||
|
||||
<p>Note that flask-dance adds an OAuth login/callback route |
||||
to your Flask app by creating a <code>/login</code> blueprint, |
||||
meaning all the OAuth stuff is just magically available |
||||
via <code>/login</code>.</p> |
||||
<p>Set paths for static content:</p> |
||||
<pre><code class="python">PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__)) |
||||
STATIC_PATH = 'content' |
||||
</code></pre> |
||||
|
||||
<p>Create and configure app. This requires confidential information |
||||
for the Github application you created, specifically the client |
||||
ID and client secret. These are at the very top of the page when |
||||
you visit your app's settings page.</p> |
||||
<p>To find this, after you log in, click your profile photo in the |
||||
upper right > Settings > Developer Settings > OAuth Apps > click the |
||||
name for your OAuth app.</p> |
||||
<pre><code class="python">app = Flask(__name__) |
||||
|
||||
# this worked locally, but not on heroku |
||||
app.wsgi_app = ProxyFix(app.wsgi_app) |
||||
|
||||
app.secret_key = os.environ.get("FLASK_SECRET_KEY", "9502861d41e8729c5cae3225920b1b46") |
||||
|
||||
app.config["RESULT_STATIC_PATH"] = STATIC_PATH #os.path.join(PROJECT_ROOT,STATIC_PATH) |
||||
app.config["GITHUB_OAUTH_CLIENT_ID"] = os.environ.get("GITHUB_OAUTH_CLIENT_ID") |
||||
app.config["GITHUB_OAUTH_CLIENT_SECRET"] = os.environ.get("GITHUB_OAUTH_CLIENT_SECRET") |
||||
</code></pre> |
||||
|
||||
<p>Now the magic happens: we use flask-dance to create a blueprint |
||||
that has methods and settings all ready to go for us to do the |
||||
OAuth dance.</p> |
||||
<p><code>make_github_blueprint()</code> is part of the contrib module of flask-dance. |
||||
There are several similar methods to generate blueprints for |
||||
authenticating with other APIs.</p> |
||||
<pre><code class="python">github_bp = make_github_blueprint( |
||||
client_id = os.environ.get('GITHUB_OAUTH_CLIENT_ID'), |
||||
client_secret = os.environ.get('GITHUB_OAUTH_CLIENT_SECRET'), |
||||
scope='read:org') |
||||
|
||||
app.register_blueprint(github_bp, url_prefix="/login") |
||||
|
||||
contents404 = "<html><body><h1>Status: Error 404 Page Not Found</h1></body></html>" |
||||
contents403 = "<html><body><h1>Status: Error 403 Access Denied</h1></body></html>" |
||||
contents200 = "<html><body><h1>Status: OK 200</h1></body></html>" |
||||
</code></pre> |
||||
|
||||
<p>Deal with the <code>/</code> route first:</p> |
||||
<ul> |
||||
<li>Check if authorized, if not, redirect them to the login URL |
||||
(magical URLs taken care of magically by our <code>make_github_blueprint</code> |
||||
function above)</li> |
||||
<li>If user is authorized (i.e., if they have gone through the OAuth |
||||
process and given their passsword to Github and been redirected |
||||
to your app with an OAuth token), then the next step is to |
||||
find out some information about them.</li> |
||||
<li>Use the <code>github</code> object to call the Github API directly.</li> |
||||
<li>Decide what to do from there.</li> |
||||
</ul> |
||||
<pre><code class="python">@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user/orgs") |
||||
if resp.ok: |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']=='rainbow-mind-machine': |
||||
</code></pre> |
||||
|
||||
<p>The next line is important to how the server works: |
||||
if all of the criteria above have been met, we return |
||||
a static file:</p> |
||||
<pre><code class="python"> return send_from_directory(STATIC_PATH, 'index.html') |
||||
</code></pre> |
||||
|
||||
<p>This is normally "bad practice," and numerous type A people |
||||
on the internet will tell you Flask should not be used for |
||||
serving static files, and that you should use nginx etc., |
||||
but these fail to igonore the following:</p> |
||||
<ul> |
||||
<li>Heroku does not let you run or configure nginx</li> |
||||
<li>For crying out loud this example is about attack rabbits |
||||
stop taking everything so seriously</li> |
||||
</ul> |
||||
<p>Now that we've got that out of the way...</p> |
||||
<p>Here's how we serve up static files. This is a total hack, |
||||
but it works. It takes any arbitrary path supplied by the |
||||
user, and attempts to find a corresponding file to serve up |
||||
on disk. </p> |
||||
<p>If the user passes a file, then that file is served up.</p> |
||||
<p>If the user passes a directory, then <code>index.html</code> is served up.</p> |
||||
<p>If the user asks for a non-existent file, a 404 error is shown.</p> |
||||
<p>If the user is not allowed to view the content, they will face |
||||
the bowel-emptying terrors of the 403 error.</p> |
||||
<pre><code class="python">@app.route('/<path:path>') |
||||
def catch_all(path): |
||||
|
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
username = github.get("/user").json()['login'] |
||||
|
||||
rsp = app.config["RESULT_STATIC_PATH"] |
||||
resp = github.get("/user/orgs") |
||||
if resp.ok: |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']=='dcppc': |
||||
|
||||
if(path==''): |
||||
return send_from_directory(rsp, 'index.html') |
||||
|
||||
elif(isdir(join(rsp,path))): |
||||
return send_from_directory(join(rsp,path),'index.html') |
||||
|
||||
elif(isfile(join(rsp,path))): |
||||
return send_from_directory(rsp, path) |
||||
|
||||
else: |
||||
return contents404 |
||||
|
||||
return contents403 |
||||
</code></pre> |
||||
|
||||
<p>Last, set a default 404 handler, and run the app:</p> |
||||
<pre><code class="python">@app.errorhandler(404) |
||||
def oops(e): |
||||
return contents404 |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
app.run() |
||||
</code></pre> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Initialize Repository: Branches |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Authenticate users based on Github membership only |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,550 @@
@@ -0,0 +1,550 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_github/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Authenticate users based on Github membership only - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#authenticate-users-on-github-membership" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Authenticate users based on Github membership only |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6" checked> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<a href="./" title="Authenticate users based on Github membership only" class="md-nav__link md-nav__link--active"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="authenticate-users-on-github-membership">Authenticate Users on Github Membership</h1> |
||||
<p>For the sake of simplicity, will just demonstrate how this |
||||
works for a single route, but you can combine different |
||||
rules into multiple routes to provide access to different |
||||
people on different parts of a site.</p> |
||||
<p>Here is the relevant method that serves up <code>index.html</code> |
||||
if the user is authenticated:</p> |
||||
<pre><code class="python">@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user") |
||||
|
||||
if resp.ok: |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
|
||||
return contents403 |
||||
</code></pre> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Create a Flask App using Flask-Dance |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Authenticate users based on organization or team membership |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,549 @@
@@ -0,0 +1,549 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_org/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Authenticate users based on organization or team membership - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#authenticate-users-on-organization-or-team-membership" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Authenticate users based on organization or team membership |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6" checked> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<a href="./" title="Authenticate users based on organization or team membership" class="md-nav__link md-nav__link--active"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="authenticate-users-on-organization-or-team-membership">Authenticate Users on Organization or Team Membership</h1> |
||||
<p>Here is how we can make access to a given page or route |
||||
conditional on membership in an organization (in this |
||||
example, membership in the <code>rainbow-mind-machine</code> organization |
||||
is required for access):</p> |
||||
<pre><code class="python">@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user/orgs") |
||||
if resp.ok: |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']=='rainbow-mind-machine': |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
</code></pre> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Authenticate users based on Github membership only |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Authenticate users based on some other criteria |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,551 @@
@@ -0,0 +1,551 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_other/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Authenticate users based on some other criteria - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#authenticate-users-on-other-criteria" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Authenticate users based on some other criteria |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6" checked> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<a href="./" title="Authenticate users based on some other criteria" class="md-nav__link md-nav__link--active"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="authenticate-users-on-other-criteria">Authenticate Users on Other Criteria</h1> |
||||
<p>Suppose we wanted to do something silly like restrict |
||||
access to a page to users with Github handles that were |
||||
between 5 and 7 letters.</p> |
||||
<p>Here is the relevant method that serves up <code>index.html</code> |
||||
if the user's Github handle is 5-7 letters long:</p> |
||||
<pre><code class="python">@app.route('/') |
||||
def index(): |
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
resp = github.get("/user") |
||||
|
||||
if resp.ok: |
||||
username = resp.json()['login'] |
||||
if len(username)>=5 and len(username)<=7: |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
|
||||
return contents403 |
||||
</code></pre> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Authenticate users based on organization or team membership |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Protection portions of the site |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,586 @@
@@ -0,0 +1,586 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_portions/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Protection portions of the site - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#authenticate-different-users-on-different-portions-of-site" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Protection portions of the site |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6" checked> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<a href="./" title="Protection portions of the site" class="md-nav__link md-nav__link--active"> |
||||
Protection portions of the site |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="authenticate-different-users-on-different-portions-of-site">Authenticate Different Users on Different Portions of Site</h1> |
||||
<p><strong>NOTE: if you are authenticating using membership on a team, you will need the |
||||
team id of the team you are interested in authenticating against.</strong></p> |
||||
<p>For this example, let's expand the routes we're looking at |
||||
a bit more.</p> |
||||
<p>Suppose we have two folders, <code>team_only</code> and <code>org_only</code>.</p> |
||||
<p>The <code>team_only</code> folder should only be accessible to your team, <code>Team Gold</code>.</p> |
||||
<p>The <code>org_only</code> folder should only be accessible to your organization, <code>Colorful Colors</code>.</p> |
||||
<p>The main site (i.e., all other files) should be publicly accessible.</p> |
||||
<pre><code class="python">@app.route('/') |
||||
def index(): |
||||
return send_from_directory(STATIC_PATH, 'index.html') |
||||
|
||||
|
||||
@app.route('/team_only/<path:path>') |
||||
def team_gold(path): |
||||
|
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
rsp = app.config["RESULT_STATIC_PATH"] |
||||
|
||||
resp = github.get("/user") |
||||
if resp.ok: |
||||
username = resp.json()['login'] |
||||
|
||||
team_id = 'XXXXX' |
||||
|
||||
resp = github.get("/teams/%s/members/%s"%( team_id, username )) |
||||
if resp.code==204: |
||||
team_gold_dir = os.path.join(STATIC_PATH, 'team_only') |
||||
return send_from_directory(team_gold_dir, 'index.html') |
||||
return contents403 |
||||
|
||||
|
||||
@app.route('/org_only/<path:path>') |
||||
def team_gold(path): |
||||
|
||||
if not github.authorized: |
||||
return redirect(url_for("github.login")) |
||||
|
||||
rsp = app.config["RESULT_STATIC_PATH"] |
||||
|
||||
resp = github.get("/user") |
||||
if resp.ok: |
||||
|
||||
my_org = 'XXXXXXXX' |
||||
|
||||
all_orgs = resp.json() |
||||
for org in all_orgs: |
||||
if org['login']==my_org: |
||||
color_org_dir = os.path.join(STATIC_PATH, 'org_only') |
||||
return send_from_directory(color_org_dir, 'index.html') |
||||
return contents403 |
||||
</code></pre> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Authenticate users based on some other criteria |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Test Flask App Locally |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,708 @@
@@ -0,0 +1,708 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_heroku/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Deploying Flask App to Heroku - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#deploying-to-heroku" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Deploying Flask App to Heroku |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__link md-nav__link--active" for="toc"> |
||||
Deploying Flask App to Heroku |
||||
</label> |
||||
|
||||
<a href="./" title="Deploying Flask App to Heroku" class="md-nav__link md-nav__link--active"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
|
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#repository-setup" title="Repository Setup" class="md-nav__link"> |
||||
Repository Setup |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#heroku-deploy-process" title="Heroku Deploy Process" class="md-nav__link"> |
||||
Heroku Deploy Process |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#heroku-login" title="Heroku Login" class="md-nav__link"> |
||||
Heroku Login |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#add-heroku-remote-to-heroku-pages-branch" title="Add Heroku Remote to heroku-pages Branch" class="md-nav__link"> |
||||
Add Heroku Remote to heroku-pages Branch |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#deploy-to-heroku" title="Deploy to Heroku" class="md-nav__link"> |
||||
Deploy to Heroku |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#check-your-heroku-app" title="Check Your Heroku App" class="md-nav__link"> |
||||
Check Your Heroku App |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#repository-setup" title="Repository Setup" class="md-nav__link"> |
||||
Repository Setup |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#heroku-deploy-process" title="Heroku Deploy Process" class="md-nav__link"> |
||||
Heroku Deploy Process |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#heroku-login" title="Heroku Login" class="md-nav__link"> |
||||
Heroku Login |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#add-heroku-remote-to-heroku-pages-branch" title="Add Heroku Remote to heroku-pages Branch" class="md-nav__link"> |
||||
Add Heroku Remote to heroku-pages Branch |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#deploy-to-heroku" title="Deploy to Heroku" class="md-nav__link"> |
||||
Deploy to Heroku |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#check-your-heroku-app" title="Check Your Heroku App" class="md-nav__link"> |
||||
Check Your Heroku App |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="deploying-to-heroku">Deploying to Heroku</h1> |
||||
<p>Once we have debugged the Flask app and we are happy with it, |
||||
we are ready to deploy it to Heroku. </p> |
||||
<h2 id="repository-setup">Repository Setup</h2> |
||||
<p>To do this, you should set up your repo as follows:</p> |
||||
<p>Clone the repo:</p> |
||||
<pre><code class="plain">$ git clone https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git |
||||
</code></pre> |
||||
|
||||
<p>The repo has the following structure:</p> |
||||
<pre><code class="plain">github-heroku-attack-rabbits/ |
||||
LICENSE |
||||
README.md |
||||
mkdocs.yml |
||||
docs/ |
||||
index.md |
||||
... |
||||
mkdocs-material/ |
||||
... |
||||
</code></pre> |
||||
|
||||
<p>Now, inside the repo, clone the repo again, |
||||
but this time clone the <code>heroku-pages</code> branch |
||||
to the <code>site/</code> directory:</p> |
||||
<pre><code class="plain">$ cd github-heroku-attack-rabbits/ |
||||
$ git clone -b heroku-pages https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git site |
||||
</code></pre> |
||||
|
||||
<h2 id="heroku-deploy-process">Heroku Deploy Process</h2> |
||||
<p>To deploy content to Heroku, we add our Heroku project as a git remote |
||||
(see the <a href="../heroku/">heroku</a> page for how to do that) and then push to |
||||
to the master branch of the heroku remote git repo. Changes are pulled |
||||
in by Heroku and the app is restarted each time you run <code>git push</code>.</p> |
||||
<p>We walk through the steps below.</p> |
||||
<h2 id="heroku-login">Heroku Login</h2> |
||||
<p>From the <code>site/</code> directory containing the contents of the <code>heroku-pages</code> branch, |
||||
that is, containing the Python flask app, log in to Heroku:</p> |
||||
<pre><code class="plain">$ heroku login |
||||
</code></pre> |
||||
|
||||
<h2 id="add-heroku-remote-to-heroku-pages-branch">Add Heroku Remote to <code>heroku-pages</code> Branch</h2> |
||||
<p>Now have Heroku add the proper git remote address:</p> |
||||
<pre><code class="plain">$ heroku git:remote -a <heroku-app-name> |
||||
</code></pre> |
||||
|
||||
<p>Now you're ready to deploy to Heroku. </p> |
||||
<h2 id="deploy-to-heroku">Deploy to Heroku</h2> |
||||
<p>Double check your app is ready, then deploy:</p> |
||||
<pre><code class="plain">$ git push heroku heroku-pages:master |
||||
</code></pre> |
||||
|
||||
<p>This will push the local branch <code>heroku-pages</code> to |
||||
the remote branch <code>master</code> on the <code>heroku</code> remote. |
||||
This should begin a pre-commit hook where Heroku |
||||
compiles your Python app. You should get the green |
||||
light, if you tested your app locally and everything |
||||
was good to go.</p> |
||||
<h2 id="check-your-heroku-app">Check Your Heroku App</h2> |
||||
<p>Your Heroku app will be available at </p> |
||||
<pre><code>https://<heroku-app-name>.herokuapp.com |
||||
</code></pre> |
||||
|
||||
<p>You should see your Python flask app |
||||
show up shortly.</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Test Flask App Locally |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../custom_domains/" title="Custom Domains" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Custom Domains |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,605 @@
@@ -0,0 +1,605 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_local/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Test Flask App Locally - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#testing-flask-app-locally" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Test Flask App Locally |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__link md-nav__link--active" for="toc"> |
||||
Test Flask App Locally |
||||
</label> |
||||
|
||||
<a href="./" title="Test Flask App Locally" class="md-nav__link md-nav__link--active"> |
||||
Test Flask App Locally |
||||
</a> |
||||
|
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#next-step" title="Next Step?" class="md-nav__link"> |
||||
Next Step? |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#next-step" title="Next Step?" class="md-nav__link"> |
||||
Next Step? |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="testing-flask-app-locally">Testing Flask App Locally</h1> |
||||
<p>We set up the Github App to use a callback of <code>https://localhost:5000/login/github/authorized</code> |
||||
so that we could test the app locally. Now it is time to test the app locally.</p> |
||||
<p>The application needs access to your Github app id and token. Those are provided |
||||
via the <code>GITHUB_OAUTH_CLIENT_{ID,SECRET}</code> environment variables. Set these |
||||
when you run the actual python command to run the server:</p> |
||||
<pre><code class="plain">$ GITHUB_OAUTH_CLIENT_ID="xxxxxxx" \ |
||||
GITHUB_OAUTH_CLIENT_SECRET="xxxxxxx" \ |
||||
OAUTHLIB_INSECURE_TRANSPORT=true \ |
||||
python github.py |
||||
</code></pre> |
||||
|
||||
<p>This runs the Flask server on port 5000, where it will wait for a visitor. |
||||
The way we have our application written in this example, the main <code>/</code> route |
||||
will redirect the user to a Github login screen immediately, but you could |
||||
also present the user with a friendly welcome page when they go to <code>/</code>, |
||||
and only redirect them to the Github login prompt when they visit a |
||||
URL like <code>/login</code> or <code>/auth</code>.</p> |
||||
<p>Once you run the above command, open the following URL in your browser:</p> |
||||
<pre><code class="plain">http://localhost:5000/ |
||||
</code></pre> |
||||
|
||||
<p><strong>NOTE: Make sure you are logged out of Github and that you clear your cookies |
||||
if you are already logged in as one user and wish to authenticate as another. |
||||
The login is <em>very</em> persistent so you may need to close and re-open your browser.</strong></p> |
||||
<p>Visiting the address above will result in your being redirected to a Github |
||||
login page. Once you login, Github will redirect the user back to the |
||||
github-heroku-attack-rabbits application with a token that the application |
||||
can use to perform actions on behalf of the user.</p> |
||||
<h2 id="next-step">Next Step?</h2> |
||||
<p>If the app works, the next step is to deploy to Heroku.</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Protection portions of the site |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Deploying Flask App to Heroku |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,656 @@
@@ -0,0 +1,656 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/github/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Get Started with Github - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#get-started-with-github" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Get Started with Github |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
<label class="md-nav__link md-nav__link--active" for="toc"> |
||||
Get Started with Github |
||||
</label> |
||||
|
||||
<a href="./" title="Get Started with Github" class="md-nav__link md-nav__link--active"> |
||||
Get Started with Github |
||||
</a> |
||||
|
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#get-started-with-github" title="Get started with Github" class="md-nav__link"> |
||||
Get started with Github |
||||
</a> |
||||
|
||||
<nav class="md-nav"> |
||||
<ul class="md-nav__list"> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#creating-github-oauth-app" title="Creating Github OAuth App" class="md-nav__link"> |
||||
Creating Github OAuth App |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
</ul> |
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#values-to-use" title="Values to use" class="md-nav__link"> |
||||
Values to use |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#get-started-with-github" title="Get started with Github" class="md-nav__link"> |
||||
Get started with Github |
||||
</a> |
||||
|
||||
<nav class="md-nav"> |
||||
<ul class="md-nav__list"> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#creating-github-oauth-app" title="Creating Github OAuth App" class="md-nav__link"> |
||||
Creating Github OAuth App |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
</ul> |
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#values-to-use" title="Values to use" class="md-nav__link"> |
||||
Values to use |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1>Get Started with Github</h1> |
||||
|
||||
<h2 id="get-started-with-github">Get started with Github</h2> |
||||
<p>We mentioned on the <a href="../heroku/">heroku</a> page that heroku |
||||
creates a remote git repository to hold the files you |
||||
want to host.</p> |
||||
<p>To use the contents of a Github repository on Heroku, |
||||
just treat it like another git remote, no special setup |
||||
is needed.</p> |
||||
<p>However, to set up your Github-Heroku attack rabbits to |
||||
authenticate a user via Github, and mercilessly attack |
||||
all intruders, you must create a Github OAuth App.</p> |
||||
<h3 id="creating-github-oauth-app">Creating Github OAuth App</h3> |
||||
<p>Log into Github</p> |
||||
<p>Go to Settings</p> |
||||
<p>Click "Developer Settings" on the left side</p> |
||||
<p>Click "New OAuth App" button in upper right</p> |
||||
<p><strong>What do these settings mean?</strong></p> |
||||
<ul> |
||||
<li> |
||||
<p><strong>Application name</strong> is what will be shown to users when they visit |
||||
a page protected by the attack rabbits and are prompted for |
||||
their password by Github.</p> |
||||
</li> |
||||
<li> |
||||
<p><strong>Homepage URL/Application description</strong> are for users who want to know more |
||||
about your killer attack rabbit Github app</p> |
||||
</li> |
||||
<li> |
||||
<p><strong>Authorization callback URL</strong> is the URL that the users will be sent to |
||||
once they authenticate with Github and they are granted an OAuth token. |
||||
This is the magic ingredient that allows you to take actions on behalf |
||||
of the account logging in.</p> |
||||
</li> |
||||
</ul> |
||||
<p>In this guide we'll cover the case of checking membership in organizations or teams, |
||||
but what your attack rabbits end up doing to determine if a user is allowed to |
||||
access your secret pages is up to you.</p> |
||||
<h2 id="values-to-use">Values to use</h2> |
||||
<p>You should set your own values for the <strong>name</strong> and <strong>description</strong> fields.</p> |
||||
<p>The <strong>home URL</strong> is not actually necessary - it is simply provided for users to |
||||
get more information about your app.</p> |
||||
<p>The most important is the <strong>callback URL</strong>, which should be set to:</p> |
||||
<pre><code>http://localhost:5000/login/github/authorized |
||||
</code></pre> |
||||
|
||||
<p>This is for testing locally <em>only</em>.</p> |
||||
<p>Don't use HTTPS in the callback URL!</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Get Started with Heroku |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Initialize Repository: Branches |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,676 @@
@@ -0,0 +1,676 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/heroku/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Get Started with Heroku - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#create-a-heroku-app" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Get Started with Heroku |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__link md-nav__link--active" for="toc"> |
||||
Get Started with Heroku |
||||
</label> |
||||
|
||||
<a href="./" title="Get Started with Heroku" class="md-nav__link md-nav__link--active"> |
||||
Get Started with Heroku |
||||
</a> |
||||
|
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#before-you-begin-install-heroku-toolbelt" title="Before you begin: install Heroku toolbelt" class="md-nav__link"> |
||||
Before you begin: install Heroku toolbelt |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#creating-a-heroku-app" title="Creating a Heroku app" class="md-nav__link"> |
||||
Creating a Heroku app |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#where-heroku-apps-live" title="Where Heroku apps live" class="md-nav__link"> |
||||
Where Heroku apps live |
||||
</a> |
||||
|
||||
<nav class="md-nav"> |
||||
<ul class="md-nav__list"> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#how-heroku-apps-work" title="How Heroku apps work" class="md-nav__link"> |
||||
How Heroku apps work |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
</ul> |
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#before-you-begin-install-heroku-toolbelt" title="Before you begin: install Heroku toolbelt" class="md-nav__link"> |
||||
Before you begin: install Heroku toolbelt |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#creating-a-heroku-app" title="Creating a Heroku app" class="md-nav__link"> |
||||
Creating a Heroku app |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#where-heroku-apps-live" title="Where Heroku apps live" class="md-nav__link"> |
||||
Where Heroku apps live |
||||
</a> |
||||
|
||||
<nav class="md-nav"> |
||||
<ul class="md-nav__list"> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#how-heroku-apps-work" title="How Heroku apps work" class="md-nav__link"> |
||||
How Heroku apps work |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
</ul> |
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="create-a-heroku-app">Create a Heroku app</h1> |
||||
<h2 id="before-you-begin-install-heroku-toolbelt">Before you begin: install Heroku toolbelt</h2> |
||||
<p>Heroku offers a really nice command line interface tool called |
||||
Heroku Toolbelt. It is available through Homebrew and Aptitude:</p> |
||||
<pre><code class="plain">$ brew install Heroku # from Mac |
||||
|
||||
$ apt-get install Heroku # from Ubuntu |
||||
</code></pre> |
||||
|
||||
<p>It will then be available on the command line as <code>Heroku</code>.</p> |
||||
<p>The first thing you should do is authenticate with |
||||
your Heroku account by running</p> |
||||
<pre><code class="plain">$ heroku login |
||||
</code></pre> |
||||
|
||||
<p>We will use this command line application for the following tasks:</p> |
||||
<ul> |
||||
<li>Create a git remote to point to the right Heroku git remote location</li> |
||||
<li>Set environment variables (for e.g. secret keys) on the remote Heroku instance</li> |
||||
<li>Get information (logs, status, etc.) about your Heroku app</li> |
||||
</ul> |
||||
<p>We will cover these commands as they come up.</p> |
||||
<h2 id="creating-a-heroku-app">Creating a Heroku app</h2> |
||||
<p>Start by creating a Heroku app.</p> |
||||
<ul> |
||||
<li>Each Heroku app must have a unique name</li> |
||||
<li>Each Heroku app creates a remote git repo</li> |
||||
<li>Master branch is what Heroku deploys publicly on Herokuapps.com</li> |
||||
<li>You will also need Heroku CLI to link your github repo to your Heroku app</li> |
||||
</ul> |
||||
<h2 id="where-heroku-apps-live">Where Heroku apps live</h2> |
||||
<p>Suppose you are creating an app called <code>my-cool-app</code> |
||||
on Heroku. Then your application will be hosted by |
||||
Heroku and will be available at the URL:</p> |
||||
<pre><code class="plain">https://my-cool-app.herokuapp.com |
||||
</code></pre> |
||||
|
||||
<h3 id="how-heroku-apps-work">How Heroku apps work</h3> |
||||
<p>If you have used Github Pages before, Heroku uses a similar |
||||
model (live hosting one particular branch of a git repository). |
||||
However, Heroku is different because you can run dynamic scripts |
||||
using Python, Ruby, PHP, etc.</p> |
||||
<p>To change the content of your Heroku app, just change the contents |
||||
of the repository, and push to master (push to the master branch of |
||||
the remote Heroku repository).</p> |
||||
<p>You will need to structure your repository carefully. |
||||
That's what this page is here to help you do. |
||||
Heroku can figure out the rest from there.</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href=".." title="Index" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Index |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../github/" title="Get Started with Github" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Get Started with Github |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
@ -0,0 +1,703 @@
@@ -0,0 +1,703 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="./"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="./assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="./assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="./assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="./css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#github-heroku-attack-rabbits" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="./img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Index |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="./img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__link md-nav__link--active" for="toc"> |
||||
Index |
||||
</label> |
||||
|
||||
<a href="." title="Index" class="md-nav__link md-nav__link--active"> |
||||
Index |
||||
</a> |
||||
|
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#whats-this-business-all-about-then" title="What's this business all about, then?" class="md-nav__link"> |
||||
What's this business all about, then? |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#where-is-everything" title="Where is everything?" class="md-nav__link"> |
||||
Where is everything? |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#contents" title="Contents" class="md-nav__link"> |
||||
Contents |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#links" title="Links" class="md-nav__link"> |
||||
Links |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#license" title="License" class="md-nav__link"> |
||||
License |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="repo/" title="Initialize Repository: Branches" class="md-nav__link"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#whats-this-business-all-about-then" title="What's this business all about, then?" class="md-nav__link"> |
||||
What's this business all about, then? |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#where-is-everything" title="Where is everything?" class="md-nav__link"> |
||||
Where is everything? |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#contents" title="Contents" class="md-nav__link"> |
||||
Contents |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#links" title="Links" class="md-nav__link"> |
||||
Links |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#license" title="License" class="md-nav__link"> |
||||
License |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="github-heroku-attack-rabbits">github-heroku-attack-rabbits</h1> |
||||
<h2 id="whats-this-business-all-about-then">What's this business all about, then?</h2> |
||||
<p>This repository helps you put access control into place to protect your secret pages by (deep breath):</p> |
||||
<p>hosting your secret page of static and/or dynamic content by using a free Heroku app |
||||
running a Python Flask server that uses Flask-Dance to authenticate visitors |
||||
with Github using OAuth which allows you fine-grained access control for your pages |
||||
using user attributes like organization or team membership or even things like how many |
||||
vowels a user has in their username. </p> |
||||
<p>Also, did I mention the attack rabbits?</p> |
||||
<p><img alt="warning: attack rabbits ahead" src="./img/warning.png" /></p> |
||||
<h2 id="where-is-everything">Where is everything?</h2> |
||||
<p>Final pages:</p> |
||||
<ul> |
||||
<li> |
||||
<p>The finished product (pages on Heroku protected by attack rabbits) |
||||
is at <a href="https://github-heroku-attack-rabbits.herokuapp.com">github-heroku-attack-rabbits.herokuapp.com</a></p> |
||||
</li> |
||||
<li> |
||||
<p>The documentation is at <a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits">pages.charlesreid1.com/github-heroku-attack-rabbits</a></p> |
||||
</li> |
||||
</ul> |
||||
<p>Two branches in this repo compose the github-heroku-attack-rabbits documentation:</p> |
||||
<ul> |
||||
<li> |
||||
<p>(<strong>YOU ARE HERE</strong>) The <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs"><code>docs</code></a> |
||||
branch contains the files needed to generate the |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits">github-heroku-attack-rabbits documentation site</a>.</p> |
||||
</li> |
||||
<li> |
||||
<p>The <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/gh-pages"><code>gh-pages</code></a> |
||||
branch contains the static files generated from the documentation. |
||||
The contents of this branch compose the |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits">github-heroku-attack-rabbits documentation site</a>.</p> |
||||
</li> |
||||
</ul> |
||||
<p>Two branches illustrate github-heroku-attack-rabbits in practice:</p> |
||||
<ul> |
||||
<li> |
||||
<p>The <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/secret"><code>secret</code></a> |
||||
branch contains the files needed to create the secret page. (This is the |
||||
"secret page source branch", so to speak.) |
||||
This repository, the one you are looking at right now, is public, so of course |
||||
these will not really be secret, but in practice the <code>secret</code> branch would |
||||
live in a private repository.</p> |
||||
</li> |
||||
<li> |
||||
<p>The <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/heroku-pages"><code>heroku-pages</code></a> |
||||
branch contains the content that is actually pushed to Heroku - that is, |
||||
the final Flask app. This includes the Flask app (Python program), in |
||||
addition to files that tell Heroku how to run the app, |
||||
plus gunicorn "middleware" scripts, plus the static content that |
||||
Flask is supposed to serve up (whatever that happens to be - in our case, |
||||
we will cover an mkdocs documentation site that is behind an authentication |
||||
layer.).</p> |
||||
</li> |
||||
</ul> |
||||
<h2 id="contents">Contents</h2> |
||||
<p>An overview of the steps:</p> |
||||
<p><a href="heroku/">Get Started with Heroku</a></p> |
||||
<p><a href="github/">Get Started with Github</a></p> |
||||
<p><a href="repo/">Initialize Repository: Branches</a></p> |
||||
<p><a href="flask/">Create a Flask App using Flask-Dance</a></p> |
||||
<ul> |
||||
<li><a href="flask_auth_github/">Authenticate users based on Github membership only</a></li> |
||||
<li><a href="flask_auth_org/">Authenticate users based on organization or team membership</a></li> |
||||
<li><a href="flask_auth_other/">Authenticate users based on some other criteria</a></li> |
||||
<li><a href="flask_auth_portions/">Protection portions of the site</a></li> |
||||
</ul> |
||||
<p><a href="flask_local/">Test Flask App Locally</a></p> |
||||
<p><a href="flask_heroku/">Deploying Flask App to Heroku</a></p> |
||||
<p><a href="custom_domains/">Custom Domains</a></p> |
||||
<h2 id="links">Links</h2> |
||||
<p>Python software used:</p> |
||||
<ul> |
||||
<li><a href="http://flask.pocoo.org/">Flask</a></li> |
||||
<li><a href="https://github.com/singingwolfboy/flask-dance">Flask-dance</a></li> |
||||
<li><a href="https://github.com/singingwolfboy/flask-dance-github">Flask-dance-github</a></li> |
||||
<li><a href="https://github.com/squidfunk/mkdocs-material">mkdocs-material (documentation theme)</a></li> |
||||
<li><a href="http://www.mkdocs.org/">mkdocs (documentation)</a></li> |
||||
</ul> |
||||
<p>Commercial services:</p> |
||||
<ul> |
||||
<li><a href="https://heroku.com">Heroku</a></li> |
||||
<li><a href="https://github.com">Github</a></li> |
||||
</ul> |
||||
<h2 id="license">License</h2> |
||||
<p>This is released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
|
||||
<a href="heroku/" title="Get Started with Heroku" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Get Started with Heroku |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="./assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:"."}})</script> |
||||
|
||||
<script src="./search/require.js"></script> |
||||
|
||||
<script src="./search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
Subproject commit ff95dcb8463eb5f8f65b14c3d145afae21671ad9 |
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
site_name: github-heroku-attack-rabbits |
||||
site_url: https://pages.charlesreid1.com/github-heroku-attack-rabbits |
||||
repo_name: charlesreid1/github-heroku-attack-rabbits |
||||
repo_url: https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits |
||||
edit_uri: "" |
||||
|
||||
|
||||
pages: |
||||
- 'Index' : 'index.md' |
||||
- 'Get Started with Heroku': 'heroku.md' |
||||
- 'Get Started with Github': 'github.md' |
||||
- 'Initialize Repository: Branches': 'repo.md' |
||||
- 'Create a Flask App using Flask-Dance': 'flask.md' |
||||
- 'Flask': |
||||
- 'Authenticate users based on Github membership only': 'flask_auth_github.md' |
||||
- 'Authenticate users based on organization or team membership': 'flask_auth_org.md' |
||||
- 'Authenticate users based on some other criteria': 'flask_auth_other.md' |
||||
- 'Protection portions of the site': 'flask_auth_portions.md' |
||||
- 'Test Flask App Locally': 'flask_local.md' |
||||
- 'Deploying Flask App to Heroku': 'flask_heroku.md' |
||||
- 'Custom Domains': 'custom_domains.md' |
||||
|
||||
copyright: 'Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br />' |
||||
|
||||
docs_dir: docs |
||||
site_dir: site |
||||
|
||||
theme: |
||||
|
||||
name: null |
||||
custom_dir: 'mkdocs-material/material' |
||||
|
||||
# pretty colors! see https://squidfunk.github.io/mkdocs-material/getting-started/#primary-colors |
||||
palette: |
||||
primary: 'blue grey' |
||||
accent: 'blue grey' |
||||
|
||||
logo: 'img/bunny.png' |
||||
|
||||
### # fun logos! see https://material.io/icons/ |
||||
### logo: |
||||
### icon: 'lock' |
||||
|
||||
font: |
||||
text: 'Questrial' |
||||
code: 'Roboto Mono' |
||||
|
||||
# this will add docs/css/custom.css to all your docs |
||||
extra_css: |
||||
- css/custom.css |
@ -0,0 +1,676 @@
@@ -0,0 +1,676 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html> |
||||
<html lang="en" class="no-js"> |
||||
<head> |
||||
|
||||
<meta charset="utf-8"> |
||||
<meta name="viewport" content="width=device-width,initial-scale=1"> |
||||
<meta http-equiv="x-ua-compatible" content="ie=edge"> |
||||
|
||||
|
||||
<link rel="canonical" href="https://pages.charlesreid1.com/github-heroku-attack-rabbits/repo/"> |
||||
|
||||
|
||||
|
||||
<meta name="lang:clipboard.copy" content="Copy to clipboard"> |
||||
|
||||
<meta name="lang:clipboard.copied" content="Copied to clipboard"> |
||||
|
||||
<meta name="lang:search.language" content="en"> |
||||
|
||||
<meta name="lang:search.pipeline.stopwords" content="True"> |
||||
|
||||
<meta name="lang:search.pipeline.trimmer" content="True"> |
||||
|
||||
<meta name="lang:search.result.none" content="No matching documents"> |
||||
|
||||
<meta name="lang:search.result.one" content="1 matching document"> |
||||
|
||||
<meta name="lang:search.result.other" content="# matching documents"> |
||||
|
||||
<meta name="lang:search.tokenizer" content="[\s\-]+"> |
||||
|
||||
<link rel="shortcut icon" href="../"> |
||||
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.2"> |
||||
|
||||
|
||||
|
||||
<title>Initialize Repository: Branches - github-heroku-attack-rabbits</title> |
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application.8d40d89b.css"> |
||||
|
||||
<link rel="stylesheet" href="../assets/stylesheets/application-palette.6079476c.css"> |
||||
|
||||
|
||||
|
||||
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script> |
||||
|
||||
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Questrial:300,400,400i,700|Roboto+Mono"> |
||||
<style>body,input{font-family:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> |
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> |
||||
|
||||
|
||||
<link rel="stylesheet" href="../css/custom.css"> |
||||
|
||||
|
||||
</head> |
||||
|
||||
|
||||
|
||||
<body dir="ltr" data-md-color-primary="red" data-md-color-accent="red"> |
||||
|
||||
<svg class="md-svg"> |
||||
<defs> |
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" |
||||
viewBox="0 0 416 448" id="github"> |
||||
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125 |
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5 |
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75 |
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 |
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360 |
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25 |
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8 |
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 |
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25 |
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75 |
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75 |
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 |
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5 |
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 |
||||
99.5z" /> |
||||
</svg> |
||||
|
||||
</defs> |
||||
</svg> |
||||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer" autocomplete="off"> |
||||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search" autocomplete="off"> |
||||
<label class="md-overlay" data-md-component="overlay" for="drawer"></label> |
||||
|
||||
<a href="#initialize-git-repository" tabindex="1" class="md-skip"> |
||||
Skip to content |
||||
</a> |
||||
|
||||
|
||||
<header class="md-header" data-md-component="header"> |
||||
<nav class="md-header-nav md-grid"> |
||||
<div class="md-flex"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<a href="https://pages.charlesreid1.com/github-heroku-attack-rabbits" title="github-heroku-attack-rabbits" class="md-header-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="24" height="24"> |
||||
|
||||
</a> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch"> |
||||
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title"> |
||||
|
||||
|
||||
<span class="md-header-nav__topic"> |
||||
github-heroku-attack-rabbits |
||||
</span> |
||||
<span class="md-header-nav__topic"> |
||||
Initialize Repository: Branches |
||||
</span> |
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
|
||||
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label> |
||||
|
||||
<div class="md-search" data-md-component="search" role="dialog"> |
||||
<label class="md-search__overlay" for="search"></label> |
||||
<div class="md-search__inner" role="search"> |
||||
<form class="md-search__form" name="search"> |
||||
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active"> |
||||
<label class="md-icon md-search__icon" for="search"></label> |
||||
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1"> |
||||
 |
||||
</button> |
||||
</form> |
||||
<div class="md-search__output"> |
||||
<div class="md-search__scrollwrap" data-md-scrollfix> |
||||
<div class="md-search-result" data-md-component="result"> |
||||
<div class="md-search-result__meta"> |
||||
Type to start searching |
||||
</div> |
||||
<ol class="md-search-result__list"></ol> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<div class="md-header-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</nav> |
||||
</header> |
||||
|
||||
<div class="md-container"> |
||||
|
||||
|
||||
|
||||
<main class="md-main"> |
||||
<div class="md-main__inner md-grid" data-md-component="container"> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
<nav class="md-nav md-nav--primary" data-md-level="0"> |
||||
<label class="md-nav__title md-nav__title--site" for="drawer"> |
||||
<span class="md-nav__button md-logo"> |
||||
|
||||
<img src="../img/bunny.png" width="48" height="48"> |
||||
|
||||
</span> |
||||
github-heroku-attack-rabbits |
||||
</label> |
||||
|
||||
<div class="md-nav__source"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits" title="Go to repository" class="md-source" data-md-source="github"> |
||||
|
||||
<div class="md-source__icon"> |
||||
<svg viewBox="0 0 24 24" width="24" height="24"> |
||||
<use xlink:href="#github" width="24" height="24"></use> |
||||
</svg> |
||||
</div> |
||||
|
||||
<div class="md-source__repository"> |
||||
charlesreid1/github-heroku-attack-rabbits |
||||
</div> |
||||
</a> |
||||
|
||||
</div> |
||||
|
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href=".." title="Index" class="md-nav__link"> |
||||
Index |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../heroku/" title="Get Started with Heroku" class="md-nav__link"> |
||||
Get Started with Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../github/" title="Get Started with Github" class="md-nav__link"> |
||||
Get Started with Github |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--active"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> |
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__link md-nav__link--active" for="toc"> |
||||
Initialize Repository: Branches |
||||
</label> |
||||
|
||||
<a href="./" title="Initialize Repository: Branches" class="md-nav__link md-nav__link--active"> |
||||
Initialize Repository: Branches |
||||
</a> |
||||
|
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#branches" title="Branches" class="md-nav__link"> |
||||
Branches |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#repo-layout" title="Repo Layout" class="md-nav__link"> |
||||
Repo Layout |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#workflow" title="Workflow" class="md-nav__link"> |
||||
Workflow |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-nav__link"> |
||||
Create a Flask App using Flask-Dance |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item md-nav__item--nested"> |
||||
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> |
||||
|
||||
<label class="md-nav__link" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="1"> |
||||
<label class="md-nav__title" for="nav-6"> |
||||
Flask |
||||
</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_github/" title="Authenticate users based on Github membership only" class="md-nav__link"> |
||||
Authenticate users based on Github membership only |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_org/" title="Authenticate users based on organization or team membership" class="md-nav__link"> |
||||
Authenticate users based on organization or team membership |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_other/" title="Authenticate users based on some other criteria" class="md-nav__link"> |
||||
Authenticate users based on some other criteria |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_auth_portions/" title="Protection portions of the site" class="md-nav__link"> |
||||
Protection portions of the site |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_local/" title="Test Flask App Locally" class="md-nav__link"> |
||||
Test Flask App Locally |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../flask_heroku/" title="Deploying Flask App to Heroku" class="md-nav__link"> |
||||
Deploying Flask App to Heroku |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="../custom_domains/" title="Custom Domains" class="md-nav__link"> |
||||
Custom Domains |
||||
</a> |
||||
</li> |
||||
|
||||
|
||||
</ul> |
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> |
||||
<div class="md-sidebar__scrollwrap"> |
||||
<div class="md-sidebar__inner"> |
||||
|
||||
<nav class="md-nav md-nav--secondary"> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label class="md-nav__title" for="toc">Table of contents</label> |
||||
<ul class="md-nav__list" data-md-scrollfix> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#branches" title="Branches" class="md-nav__link"> |
||||
Branches |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#repo-layout" title="Repo Layout" class="md-nav__link"> |
||||
Repo Layout |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
<li class="md-nav__item"> |
||||
<a href="#workflow" title="Workflow" class="md-nav__link"> |
||||
Workflow |
||||
</a> |
||||
|
||||
</li> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul> |
||||
|
||||
</nav> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="md-content"> |
||||
<article class="md-content__inner md-typeset"> |
||||
|
||||
|
||||
|
||||
<h1 id="initialize-git-repository">Initialize Git Repository</h1> |
||||
<p>Let's talk through how a repository should be laid out |
||||
if we're going to be hosting a Flask app on Heroku.</p> |
||||
<h2 id="branches">Branches</h2> |
||||
<p>We will need a minimum of two branches. Here we specify |
||||
the names that these branches will have in your Github repo, |
||||
<strong>which is different from the names of the branches on Heroku</strong>:</p> |
||||
<p>Branches on Github:</p> |
||||
<ul> |
||||
<li> |
||||
<p><code>heroku-pages</code> - this branch contains the content that Heroku will host. |
||||
Specifically, it contains the Flask application in a <code>.py</code> file, |
||||
and a few other files to help Heroku determine how to run the app |
||||
and what to install.</p> |
||||
</li> |
||||
<li> |
||||
<p><code>master</code> - this branch contains the content used to generate the documentation |
||||
and page content that is being hosted behind the Heroku attack sheep. |
||||
The documentation you are reading right now is from the master branch, |
||||
and was made with <code>mkdocs</code>.</p> |
||||
</li> |
||||
</ul> |
||||
<p>On Heroku, we only have a single branch:</p> |
||||
<ul> |
||||
<li><code>master</code> (Heroku) maps to <code>heroku-pages</code> (Github)</li> |
||||
</ul> |
||||
<h2 id="repo-layout">Repo Layout</h2> |
||||
<p>Let's talk about the layout of the repository.</p> |
||||
<p>If you wish to build the site in order to deploy it to Heroku, |
||||
you should clone the <code>master</code> branch (preparing to make the |
||||
content for your attack sheep-protected page):</p> |
||||
<pre><code class="plain">$ git clone -b master https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git |
||||
$ cd github-heroku-attack-rabbits |
||||
</code></pre> |
||||
|
||||
<p>Once you are <em>inside</em> the master branch, clone the repo again, |
||||
but this time clone the <code>heroku-pages</code> branch, and clone it |
||||
to the <code>site/</code> folder:</p> |
||||
<pre><code class="plain">$ git clone -b heroku-pages https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits.git site |
||||
$ cd site |
||||
</code></pre> |
||||
|
||||
<p>Now you will want to set up the Heroku remote:</p> |
||||
<pre><code class="plain">$ heroku git:remote -a my-cool-project |
||||
</code></pre> |
||||
|
||||
<p>The layout should now be:</p> |
||||
<pre><code class="plain">my-cool-project-repo/ <-- my-cool-project repo pointing to master branch |
||||
|
||||
docs/ \ |
||||
index.md | |
||||
heroku.md | <-- mkdocs files |
||||
... | (can use any static content generator: |
||||
| pelican, sphinx, etc.) |
||||
mkdocs.yml / |
||||
|
||||
site/ <-- my-cool-project repo pointing to heroku-pages branch |
||||
|
||||
Procfile \ |
||||
github.py | <-- heroku python app files |
||||
requirements.txt | (can also use ruby, php, js, etc.) |
||||
runtime.txt | (can also use ruby, php, js, etc.) |
||||
... / |
||||
|
||||
content/ \ |
||||
index.html | <-- static content hosted by Flask |
||||
sitemap.xml | |
||||
... / |
||||
</code></pre> |
||||
|
||||
<h2 id="workflow">Workflow</h2> |
||||
<p>Once you have things set up according to the instructions and diagram above, |
||||
you're ready to run the push-to-deploy workflow and start running your secret |
||||
site on Heroku.</p> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article> |
||||
</div> |
||||
</div> |
||||
</main> |
||||
|
||||
|
||||
<footer class="md-footer"> |
||||
|
||||
<div class="md-footer-nav"> |
||||
<nav class="md-footer-nav__inner md-grid"> |
||||
|
||||
<a href="../github/" title="Get Started with Github" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Previous |
||||
</span> |
||||
Get Started with Github |
||||
</span> |
||||
</div> |
||||
</a> |
||||
|
||||
|
||||
<a href="../flask/" title="Create a Flask App using Flask-Dance" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> |
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> |
||||
<span class="md-flex__ellipsis"> |
||||
<span class="md-footer-nav__direction"> |
||||
Next |
||||
</span> |
||||
Create a Flask App using Flask-Dance |
||||
</span> |
||||
</div> |
||||
<div class="md-flex__cell md-flex__cell--shrink"> |
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> |
||||
</div> |
||||
</a> |
||||
|
||||
</nav> |
||||
</div> |
||||
|
||||
<div class="md-footer-meta md-typeset"> |
||||
<div class="md-footer-meta__inner md-grid"> |
||||
<div class="md-footer-copyright"> |
||||
|
||||
<div class="md-footer-copyright__highlight"> |
||||
Copyright © 2018 Charles Reid, released under the <a href="https://git.charlesreid1.com/charlesreid1/github-heroku-attack-rabbits/src/branch/docs/LICENSE">WTFPL</a>.<br /><br />Many Bothans died to bring us this documentation.<br /><br /> |
||||
</div> |
||||
|
||||
powered by |
||||
<a href="http://www.mkdocs.org">MkDocs</a> |
||||
and |
||||
<a href="https://squidfunk.github.io/mkdocs-material/"> |
||||
Material for MkDocs</a> |
||||
</div> |
||||
|
||||
|
||||
|
||||
</div> |
||||
</div> |
||||
</footer> |
||||
|
||||
</div> |
||||
|
||||
<script src="../assets/javascripts/application.0cf9b500.js"></script> |
||||
|
||||
<script>app.initialize({version:"0.17.3",url:{base:".."}})</script> |
||||
|
||||
<script src="../search/require.js"></script> |
||||
|
||||
<script src="../search/search.js"></script> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
/* |
||||
RequireJS 2.1.16 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved. |
||||
Available via the MIT or new BSD license. |
||||
see: http://github.com/jrburke/requirejs for details
|
||||
*/ |
||||
var requirejs,require,define; |
||||
(function(ba){function G(b){return"[object Function]"===K.call(b)}function H(b){return"[object Array]"===K.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function T(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function t(b,c){return fa.call(b,c)}function m(b,c){return t(b,c)&&b[c]}function B(b,c){for(var d in b)if(t(b,d)&&c(b[d],d))break}function U(b,c,d,e){c&&B(c,function(c,g){if(d||!t(b,g))e&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof |
||||
RegExp)?(b[g]||(b[g]={}),U(b[g],c,d,e)):b[g]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function ca(b){throw b;}function da(b){if(!b)return b;var c=ba;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,e){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=e;d&&(c.originalError=d);return c}function ga(b){function c(a,k,b){var f,l,c,d,e,g,i,p,k=k&&k.split("/"),h=j.map,n=h&&h["*"];if(a){a=a.split("/");l=a.length-1;j.nodeIdCompat&& |
||||
Q.test(a[l])&&(a[l]=a[l].replace(Q,""));"."===a[0].charAt(0)&&k&&(l=k.slice(0,k.length-1),a=l.concat(a));l=a;for(c=0;c<l.length;c++)if(d=l[c],"."===d)l.splice(c,1),c-=1;else if(".."===d&&!(0===c||1==c&&".."===l[2]||".."===l[c-1])&&0<c)l.splice(c-1,2),c-=2;a=a.join("/")}if(b&&h&&(k||n)){l=a.split("/");c=l.length;a:for(;0<c;c-=1){e=l.slice(0,c).join("/");if(k)for(d=k.length;0<d;d-=1)if(b=m(h,k.slice(0,d).join("/")))if(b=m(b,e)){f=b;g=c;break a}!i&&(n&&m(n,e))&&(i=m(n,e),p=c)}!f&&i&&(f=i,g=p);f&&(l.splice(0, |
||||
g,f),a=l.join("/"))}return(f=m(j.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(k){if(k.getAttribute("data-requiremodule")===a&&k.getAttribute("data-requirecontext")===i.contextName)return k.parentNode.removeChild(k),!0})}function e(a){var k=m(j.paths,a);if(k&&H(k)&&1<k.length)return k.shift(),i.require.undef(a),i.makeRequire(null,{skipMap:!0})([a]),!0}function n(a){var k,c=a?a.indexOf("!"):-1;-1<c&&(k=a.substring(0,c),a=a.substring(c+1,a.length));return[k,a]}function p(a, |
||||
k,b,f){var l,d,e=null,g=k?k.name:null,j=a,p=!0,h="";a||(p=!1,a="_@r"+(K+=1));a=n(a);e=a[0];a=a[1];e&&(e=c(e,g,f),d=m(r,e));a&&(e?h=d&&d.normalize?d.normalize(a,function(a){return c(a,g,f)}):-1===a.indexOf("!")?c(a,g,f):a:(h=c(a,g,f),a=n(h),e=a[0],h=a[1],b=!0,l=i.nameToUrl(h)));b=e&&!d&&!b?"_unnormalized"+(O+=1):"";return{prefix:e,name:h,parentMap:k,unnormalized:!!b,url:l,originalName:j,isDefine:p,id:(e?e+"!"+h:h)+b}}function s(a){var k=a.id,b=m(h,k);b||(b=h[k]=new i.Module(a));return b}function q(a, |
||||
k,b){var f=a.id,c=m(h,f);if(t(r,f)&&(!c||c.defineEmitComplete))"defined"===k&&b(r[f]);else if(c=s(a),c.error&&"error"===k)b(c.error);else c.on(k,b)}function w(a,b){var c=a.requireModules,f=!1;if(b)b(a);else if(v(c,function(b){if(b=m(h,b))b.error=a,b.events.error&&(f=!0,b.emit("error",a))}),!f)g.onError(a)}function x(){R.length&&(ha.apply(A,[A.length,0].concat(R)),R=[])}function y(a){delete h[a];delete V[a]}function F(a,b,c){var f=a.map.id;a.error?a.emit("error",a.error):(b[f]=!0,v(a.depMaps,function(f, |
||||
d){var e=f.id,g=m(h,e);g&&(!a.depMatched[d]&&!c[e])&&(m(b,e)?(a.defineDep(d,r[e]),a.check()):F(g,b,c))}),c[f]=!0)}function D(){var a,b,c=(a=1E3*j.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],l=[],g=!1,h=!0;if(!W){W=!0;B(V,function(a){var i=a.map,j=i.id;if(a.enabled&&(i.isDefine||l.push(a),!a.error))if(!a.inited&&c)e(j)?g=b=!0:(f.push(j),d(j));else if(!a.inited&&(a.fetched&&i.isDefine)&&(g=!0,!i.prefix))return h=!1});if(c&&f.length)return a=C("timeout","Load timeout for modules: "+f,null, |
||||
f),a.contextName=i.contextName,w(a);h&&v(l,function(a){F(a,{},{})});if((!c||b)&&g)if((z||ea)&&!X)X=setTimeout(function(){X=0;D()},50);W=!1}}function E(a){t(r,a[0])||s(p(a[0],null,!0)).init(a[1],a[2])}function I(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!Y?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||Y)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function J(){var a; |
||||
for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var W,Z,i,L,X,j={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},h={},V={},$={},A=[],r={},S={},aa={},K=1,O=1;L={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?r[a.map.id]=a.exports:a.exports=r[a.map.id]={}},module:function(a){return a.module? |
||||
a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return m(j.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};Z=function(a){this.events=m($,a.id)||{};this.map=a;this.shim=m(j.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Z.prototype={init:function(a,b,c,f){f=f||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback= |
||||
c;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a= |
||||
this.map.url;S[a]||(S[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var f=this.exports,l=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(l)){if(this.events.error&&this.map.isDefine||g.onError!==ca)try{f=i.execCb(c,l,b,f)}catch(d){a=d}else f=i.execCb(c,l,b,f);this.map.isDefine&&void 0===f&&((b=this.module)?f=b.exports:this.usingExports&& |
||||
(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(r[c]=f,g.onResourceLoad))g.onResourceLoad(i,this.map,this.depMaps);y(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= |
||||
this.map,b=a.id,d=p(a.prefix);this.depMaps.push(d);q(d,"defined",u(this,function(f){var l,d;d=m(aa,this.map.id);var e=this.map.name,P=this.map.parentMap?this.map.parentMap.name:null,n=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(e=f.normalize(e,function(a){return c(a,P,!0)})||""),f=p(a.prefix+"!"+e,this.map.parentMap),q(f,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(h,f.id)){this.depMaps.push(f); |
||||
if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else d?(this.map.url=i.nameToUrl(d),this.load()):(l=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(h,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),l.fromText=u(this,function(f,c){var d=a.name,e=p(d),P=M;c&&(f=c);P&&(M=!1);s(e);t(j.config,b)&&(j.config[d]=j.config[b]);try{g.exec(f)}catch(h){return w(C("fromtexteval", |
||||
"fromText eval for "+b+" failed: "+h,h,[b]))}P&&(M=!0);this.depMaps.push(e);i.completeLoad(d);n([d],l)}),f.load(a.name,n,l,j))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,u(this,function(a,b){var c,f;if("string"===typeof a){a=p(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(L,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;q(a,"defined",u(this,function(a){this.defineDep(b, |
||||
a);this.check()}));this.errback?q(a,"error",u(this,this.errback)):this.events.error&&q(a,"error",u(this,function(a){this.emit("error",a)}))}c=a.id;f=h[c];!t(L,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,u(this,function(a){var b=m(h,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:j,contextName:b, |
||||
registry:h,defined:r,urlFetched:S,defQueue:A,Module:Z,makeModuleMap:p,nextTick:g.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=j.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(j[b]||(j[b]={}),U(j[b],a,!0,!0)):j[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(aa[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a); |
||||
b[c]=a}),j.shim=b);a.packages&&v(a.packages,function(a){var b,a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(j.paths[b]=a.location);j.pkgs[b]=a.name+"/"+(a.main||"main").replace(ia,"").replace(Q,"")});B(h,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=p(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ba,arguments));return b||a.exports&&da(a.exports)}},makeRequire:function(a,e){function j(c,d,m){var n, |
||||
q;e.enableBuildCallback&&(d&&G(d))&&(d.__requireJsBuild=!0);if("string"===typeof c){if(G(d))return w(C("requireargs","Invalid require call"),m);if(a&&t(L,c))return L[c](h[a.id]);if(g.get)return g.get(i,c,a,j);n=p(c,a,!1,!0);n=n.id;return!t(r,n)?w(C("notloaded",'Module name "'+n+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[n]}J();i.nextTick(function(){J();q=s(p(null,a));q.skipMap=e.skipMap;q.init(c,d,m,{enabled:!0});D()});return j}e=e||{};U(j,{isBrowser:z,toUrl:function(b){var d, |
||||
e=b.lastIndexOf("."),k=b.split("/")[0];if(-1!==e&&(!("."===k||".."===k)||1<e))d=b.substring(e,b.length),b=b.substring(0,e);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return t(r,p(b,a,!1,!0).id)},specified:function(b){b=p(b,a,!1,!0).id;return t(r,b)||t(h,b)}});a||(j.undef=function(b){x();var c=p(b,a,!0),e=m(h,b);d(b);delete r[b];delete S[c.url];delete $[b];T(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&($[b]=e.events),y(b))});return j},enable:function(a){m(h,a.id)&& |
||||
s(a).enable()},completeLoad:function(a){var b,c,d=m(j.shim,a)||{},g=d.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=m(h,a);if(!b&&!t(r,a)&&c&&!c.inited){if(j.enforceDefine&&(!g||!da(g)))return e(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,d.deps||[],d.exportsFn])}D()},nameToUrl:function(a,b,c){var d,e,h;(d=m(j.pkgs,a))&&(a=d);if(d=m(aa,a))return i.nameToUrl(d,b,c);if(g.jsExtRegExp.test(a))d=a+(b||"");else{d=j.paths; |
||||
a=a.split("/");for(e=a.length;0<e;e-=1)if(h=a.slice(0,e).join("/"),h=m(d,h)){H(h)&&(h=h[0]);a.splice(0,e,h);break}d=a.join("/");d+=b||(/^data\:|\?/.test(d)||c?"":".js");d=("/"===d.charAt(0)||d.match(/^[\w\+\.\-]+:/)?"":j.baseUrl)+d}return j.urlArgs?d+((-1===d.indexOf("?")?"?":"&")+j.urlArgs):d},load:function(a,b){g.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ja.test((a.currentTarget||a.srcElement).readyState))N=null,a=I(a),i.completeLoad(a.id)}, |
||||
onScriptError:function(a){var b=I(a);if(!e(b.id))return w(C("scripterror","Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var g,x,y,D,I,E,N,J,s,O,ka=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,la=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,Q=/\.js$/,ia=/^\.\//;x=Object.prototype;var K=x.toString,fa=x.hasOwnProperty,ha=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),ea=!z&&"undefined"!==typeof importScripts,ja= |
||||
z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,Y="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},q={},R=[],M=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;q=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(q=require,require=void 0);g=requirejs=function(b,c,d,e){var n,p="_";!H(b)&&"string"!==typeof b&&(n=b,H(c)?(b=c,c=d,d=e):b=[]);n&&n.context&&(p=n.context);(e=m(F,p))||(e=F[p]=g.s.newContext(p)); |
||||
n&&e.configure(n);return e.require(b,c,d)};g.config=function(b){return g(b)};g.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=g);g.version="2.1.16";g.jsExtRegExp=/^\/|:|\?|\.js$/;g.isBrowser=z;x=g.s={contexts:F,newContext:ga};g({});v(["toUrl","undef","defined","specified"],function(b){g[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y= |
||||
x.head=D.parentNode;g.onError=ca;g.createNode=function(b){var c=b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};g.load=function(b,c,d){var e=b&&b.config||{};if(z)return e=g.createNode(e,c,d),e.setAttribute("data-requirecontext",b.contextName),e.setAttribute("data-requiremodule",c),e.attachEvent&&!(e.attachEvent.toString&&0>e.attachEvent.toString().indexOf("[native code"))&& |
||||
!Y?(M=!0,e.attachEvent("onreadystatechange",b.onScriptLoad)):(e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)),e.src=d,J=e,D?y.insertBefore(e,D):y.appendChild(e),J=null,e;if(ea)try{importScripts(d),b.completeLoad(c)}catch(m){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,m,[c]))}};z&&!q.skipDataMain&&T(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(I=b.getAttribute("data-main"))return s=I,q.baseUrl||(E=s.split("/"), |
||||
s=E.pop(),O=E.length?E.join("/")+"/":"./",q.baseUrl=O),s=s.replace(Q,""),g.jsExtRegExp.test(s)&&(s=I),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var e,g;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(ka,"").replace(la,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(M){if(!(e=J))N&&"interactive"===N.readyState||T(document.getElementsByTagName("script"),function(b){if("interactive"=== |
||||
b.readyState)return N=b}),e=N;e&&(b||(b=e.getAttribute("data-requiremodule")),g=F[e.getAttribute("data-requirecontext")])}(g?g.defQueue:R).push([b,c,d])};define.amd={jQuery:!0};g.exec=function(b){return eval(b)};g(q)}})(this); |
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
<article> |
||||
<h3><a href="{{location}}">{{title}}</a></h3> |
||||
<p>{{summary}}</p> |
||||
</article> |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
require.config({ |
||||
baseUrl: base_url + "/search/" |
||||
}); |
||||
|
||||
require([ |
||||
'mustache.min', |
||||
'lunr.min', |
||||
'text!search-results-template.mustache', |
||||
'text!search_index.json', |
||||
], function (Mustache, lunr, results_template, data) { |
||||
"use strict"; |
||||
|
||||
function getSearchTerm() |
||||
{ |
||||
var sPageURL = window.location.search.substring(1); |
||||
var sURLVariables = sPageURL.split('&'); |
||||
for (var i = 0; i < sURLVariables.length; i++) |
||||
{ |
||||
var sParameterName = sURLVariables[i].split('='); |
||||
if (sParameterName[0] == 'q') |
||||
{ |
||||
return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20')); |
||||
} |
||||
} |
||||
} |
||||
|
||||
var index = lunr(function () { |
||||
this.field('title', {boost: 10}); |
||||
this.field('text'); |
||||
this.ref('location'); |
||||
}); |
||||
|
||||
data = JSON.parse(data); |
||||
var documents = {}; |
||||
|
||||
for (var i=0; i < data.docs.length; i++){ |
||||
var doc = data.docs[i]; |
||||
doc.location = base_url + doc.location; |
||||
index.add(doc); |
||||
documents[doc.location] = doc; |
||||
} |
||||
|
||||
var search = function(){ |
||||
|
||||
var query = document.getElementById('mkdocs-search-query').value; |
||||
var search_results = document.getElementById("mkdocs-search-results"); |
||||
while (search_results.firstChild) { |
||||
search_results.removeChild(search_results.firstChild); |
||||
} |
||||
|
||||
if(query === ''){ |
||||
return; |
||||
} |
||||
|
||||
var results = index.search(query); |
||||
|
||||
if (results.length > 0){ |
||||
for (var i=0; i < results.length; i++){ |
||||
var result = results[i]; |
||||
doc = documents[result.ref]; |
||||
doc.base_url = base_url; |
||||
doc.summary = doc.text.substring(0, 200); |
||||
var html = Mustache.to_html(results_template, doc); |
||||
search_results.insertAdjacentHTML('beforeend', html); |
||||
} |
||||
} else { |
||||
search_results.insertAdjacentHTML('beforeend', "<p>No results found</p>"); |
||||
} |
||||
|
||||
if(jQuery){ |
||||
/* |
||||
* We currently only automatically hide bootstrap models. This |
||||
* requires jQuery to work. |
||||
*/ |
||||
jQuery('#mkdocs_search_modal a').click(function(){ |
||||
jQuery('#mkdocs_search_modal').modal('hide'); |
||||
}); |
||||
} |
||||
|
||||
}; |
||||
|
||||
var search_input = document.getElementById('mkdocs-search-query'); |
||||
|
||||
var term = getSearchTerm(); |
||||
if (term){ |
||||
search_input.value = term; |
||||
search(); |
||||
} |
||||
|
||||
if (search_input){search_input.addEventListener("keyup", search);} |
||||
|
||||
}); |
@ -0,0 +1,390 @@
@@ -0,0 +1,390 @@
|
||||
/** |
||||
* @license RequireJS text 2.0.12 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. |
||||
* Available via the MIT or new BSD license. |
||||
* see: http://github.com/requirejs/text for details
|
||||
*/ |
||||
/*jslint regexp: true */ |
||||
/*global require, XMLHttpRequest, ActiveXObject, |
||||
define, window, process, Packages, |
||||
java, location, Components, FileUtils */ |
||||
|
||||
define(['module'], function (module) { |
||||
'use strict'; |
||||
|
||||
var text, fs, Cc, Ci, xpcIsWindows, |
||||
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], |
||||
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, |
||||
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im, |
||||
hasLocation = typeof location !== 'undefined' && location.href, |
||||
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), |
||||
defaultHostName = hasLocation && location.hostname, |
||||
defaultPort = hasLocation && (location.port || undefined), |
||||
buildMap = {}, |
||||
masterConfig = (module.config && module.config()) || {}; |
||||
|
||||
text = { |
||||
version: '2.0.12', |
||||
|
||||
strip: function (content) { |
||||
//Strips <?xml ...?> declarations so that external SVG and XML
|
||||
//documents can be added to a document without worry. Also, if the string
|
||||
//is an HTML document, only the part inside the body tag is returned.
|
||||
if (content) { |
||||
content = content.replace(xmlRegExp, ""); |
||||
var matches = content.match(bodyRegExp); |
||||
if (matches) { |
||||
content = matches[1]; |
||||
} |
||||
} else { |
||||
content = ""; |
||||
} |
||||
return content; |
||||
}, |
||||
|
||||
jsEscape: function (content) { |
||||
return content.replace(/(['\\])/g, '\\$1') |
||||
.replace(/[\f]/g, "\\f") |
||||
.replace(/[\b]/g, "\\b") |
||||
.replace(/[\n]/g, "\\n") |
||||
.replace(/[\t]/g, "\\t") |
||||
.replace(/[\r]/g, "\\r") |
||||
.replace(/[\u2028]/g, "\\u2028") |
||||
.replace(/[\u2029]/g, "\\u2029"); |
||||
}, |
||||
|
||||
createXhr: masterConfig.createXhr || function () { |
||||
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
|
||||
var xhr, i, progId; |
||||
if (typeof XMLHttpRequest !== "undefined") { |
||||
return new XMLHttpRequest(); |
||||
} else if (typeof ActiveXObject !== "undefined") { |
||||
for (i = 0; i < 3; i += 1) { |
||||
progId = progIds[i]; |
||||
try { |
||||
xhr = new ActiveXObject(progId); |
||||
} catch (e) {} |
||||
|
||||
if (xhr) { |
||||
progIds = [progId]; // so faster next time
|
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return xhr; |
||||
}, |
||||
|
||||
/** |
||||
* Parses a resource name into its component parts. Resource names |
||||
* look like: module/name.ext!strip, where the !strip part is |
||||
* optional. |
||||
* @param {String} name the resource name |
||||
* @returns {Object} with properties "moduleName", "ext" and "strip" |
||||
* where strip is a boolean. |
||||
*/ |
||||
parseName: function (name) { |
||||
var modName, ext, temp, |
||||
strip = false, |
||||
index = name.indexOf("."), |
||||
isRelative = name.indexOf('./') === 0 || |
||||
name.indexOf('../') === 0; |
||||
|
||||
if (index !== -1 && (!isRelative || index > 1)) { |
||||
modName = name.substring(0, index); |
||||
ext = name.substring(index + 1, name.length); |
||||
} else { |
||||
modName = name; |
||||
} |
||||
|
||||
temp = ext || modName; |
||||
index = temp.indexOf("!"); |
||||
if (index !== -1) { |
||||
//Pull off the strip arg.
|
||||
strip = temp.substring(index + 1) === "strip"; |
||||
temp = temp.substring(0, index); |
||||
if (ext) { |
||||
ext = temp; |
||||
} else { |
||||
modName = temp; |
||||
} |
||||
} |
||||
|
||||
return { |
||||
moduleName: modName, |
||||
ext: ext, |
||||
strip: strip |
||||
}; |
||||
}, |
||||
|
||||
xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/, |
||||
|
||||
/** |
||||
* Is an URL on another domain. Only works for browser use, returns |
||||
* false in non-browser environments. Only used to know if an |
||||
* optimized .js version of a text resource should be loaded |
||||
* instead. |
||||
* @param {String} url |
||||
* @returns Boolean |
||||
*/ |
||||
useXhr: function (url, protocol, hostname, port) { |
||||
var uProtocol, uHostName, uPort, |
||||
match = text.xdRegExp.exec(url); |
||||
if (!match) { |
||||
return true; |
||||
} |
||||
uProtocol = match[2]; |
||||
uHostName = match[3]; |
||||
|
||||
uHostName = uHostName.split(':'); |
||||
uPort = uHostName[1]; |
||||
uHostName = uHostName[0]; |
||||
|
||||
return (!uProtocol || uProtocol === protocol) && |
||||
(!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) && |
||||
((!uPort && !uHostName) || uPort === port); |
||||
}, |
||||
|
||||
finishLoad: function (name, strip, content, onLoad) { |
||||
content = strip ? text.strip(content) : content; |
||||
if (masterConfig.isBuild) { |
||||
buildMap[name] = content; |
||||
} |
||||
onLoad(content); |
||||
}, |
||||
|
||||
load: function (name, req, onLoad, config) { |
||||
//Name has format: some.module.filext!strip
|
||||
//The strip part is optional.
|
||||
//if strip is present, then that means only get the string contents
|
||||
//inside a body tag in an HTML string. For XML/SVG content it means
|
||||
//removing the <?xml ...?> declarations so the content can be inserted
|
||||
//into the current doc without problems.
|
||||
|
||||
// Do not bother with the work if a build and text will
|
||||
// not be inlined.
|
||||
if (config && config.isBuild && !config.inlineText) { |
||||
onLoad(); |
||||
return; |
||||
} |
||||
|
||||
masterConfig.isBuild = config && config.isBuild; |
||||
|
||||
var parsed = text.parseName(name), |
||||
nonStripName = parsed.moduleName + |
||||
(parsed.ext ? '.' + parsed.ext : ''), |
||||
url = req.toUrl(nonStripName), |
||||
useXhr = (masterConfig.useXhr) || |
||||
text.useXhr; |
||||
|
||||
// Do not load if it is an empty: url
|
||||
if (url.indexOf('empty:') === 0) { |
||||
onLoad(); |
||||
return; |
||||
} |
||||
|
||||
//Load the text. Use XHR if possible and in a browser.
|
||||
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { |
||||
text.get(url, function (content) { |
||||
text.finishLoad(name, parsed.strip, content, onLoad); |
||||
}, function (err) { |
||||
if (onLoad.error) { |
||||
onLoad.error(err); |
||||
} |
||||
}); |
||||
} else { |
||||
//Need to fetch the resource across domains. Assume
|
||||
//the resource has been optimized into a JS module. Fetch
|
||||
//by the module name + extension, but do not include the
|
||||
//!strip part to avoid file system issues.
|
||||
req([nonStripName], function (content) { |
||||
text.finishLoad(parsed.moduleName + '.' + parsed.ext, |
||||
parsed.strip, content, onLoad); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
write: function (pluginName, moduleName, write, config) { |
||||
if (buildMap.hasOwnProperty(moduleName)) { |
||||
var content = text.jsEscape(buildMap[moduleName]); |
||||
write.asModule(pluginName + "!" + moduleName, |
||||
"define(function () { return '" + |
||||
content + |
||||
"';});\n"); |
||||
} |
||||
}, |
||||
|
||||
writeFile: function (pluginName, moduleName, req, write, config) { |
||||
var parsed = text.parseName(moduleName), |
||||
extPart = parsed.ext ? '.' + parsed.ext : '', |
||||
nonStripName = parsed.moduleName + extPart, |
||||
//Use a '.js' file name so that it indicates it is a
|
||||
//script that can be loaded across domains.
|
||||
fileName = req.toUrl(parsed.moduleName + extPart) + '.js'; |
||||
|
||||
//Leverage own load() method to load plugin value, but only
|
||||
//write out values that do not have the strip argument,
|
||||
//to avoid any potential issues with ! in file names.
|
||||
text.load(nonStripName, req, function (value) { |
||||
//Use own write() method to construct full module value.
|
||||
//But need to create shell that translates writeFile's
|
||||
//write() to the right interface.
|
||||
var textWrite = function (contents) { |
||||
return write(fileName, contents); |
||||
}; |
||||
textWrite.asModule = function (moduleName, contents) { |
||||
return write.asModule(moduleName, fileName, contents); |
||||
}; |
||||
|
||||
text.write(pluginName, nonStripName, textWrite, config); |
||||
}, config); |
||||
} |
||||
}; |
||||
|
||||
if (masterConfig.env === 'node' || (!masterConfig.env && |
||||
typeof process !== "undefined" && |
||||
process.versions && |
||||
!!process.versions.node && |
||||
!process.versions['node-webkit'])) { |
||||
//Using special require.nodeRequire, something added by r.js.
|
||||
fs = require.nodeRequire('fs'); |
||||
|
||||
text.get = function (url, callback, errback) { |
||||
try { |
||||
var file = fs.readFileSync(url, 'utf8'); |
||||
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
|
||||
if (file.indexOf('\uFEFF') === 0) { |
||||
file = file.substring(1); |
||||
} |
||||
callback(file); |
||||
} catch (e) { |
||||
if (errback) { |
||||
errback(e); |
||||
} |
||||
} |
||||
}; |
||||
} else if (masterConfig.env === 'xhr' || (!masterConfig.env && |
||||
text.createXhr())) { |
||||
text.get = function (url, callback, errback, headers) { |
||||
var xhr = text.createXhr(), header; |
||||
xhr.open('GET', url, true); |
||||
|
||||
//Allow plugins direct access to xhr headers
|
||||
if (headers) { |
||||
for (header in headers) { |
||||
if (headers.hasOwnProperty(header)) { |
||||
xhr.setRequestHeader(header.toLowerCase(), headers[header]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//Allow overrides specified in config
|
||||
if (masterConfig.onXhr) { |
||||
masterConfig.onXhr(xhr, url); |
||||
} |
||||
|
||||
xhr.onreadystatechange = function (evt) { |
||||
var status, err; |
||||
//Do not explicitly handle errors, those should be
|
||||
//visible via console output in the browser.
|
||||
if (xhr.readyState === 4) { |
||||
status = xhr.status || 0; |
||||
if (status > 399 && status < 600) { |
||||
//An http 4xx or 5xx error. Signal an error.
|
||||
err = new Error(url + ' HTTP status: ' + status); |
||||
err.xhr = xhr; |
||||
if (errback) { |
||||
errback(err); |
||||
} |
||||
} else { |
||||
callback(xhr.responseText); |
||||
} |
||||
|
||||
if (masterConfig.onXhrComplete) { |
||||
masterConfig.onXhrComplete(xhr, url); |
||||
} |
||||
} |
||||
}; |
||||
xhr.send(null); |
||||
}; |
||||
} else if (masterConfig.env === 'rhino' || (!masterConfig.env && |
||||
typeof Packages !== 'undefined' && typeof java !== 'undefined')) { |
||||
//Why Java, why is this so awkward?
|
||||
text.get = function (url, callback) { |
||||
var stringBuffer, line, |
||||
encoding = "utf-8", |
||||
file = new java.io.File(url), |
||||
lineSeparator = java.lang.System.getProperty("line.separator"), |
||||
input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), |
||||
content = ''; |
||||
try { |
||||
stringBuffer = new java.lang.StringBuffer(); |
||||
line = input.readLine(); |
||||
|
||||
// Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
|
||||
// http://www.unicode.org/faq/utf_bom.html
|
||||
|
||||
// Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
|
||||
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
|
||||
if (line && line.length() && line.charAt(0) === 0xfeff) { |
||||
// Eat the BOM, since we've already found the encoding on this file,
|
||||
// and we plan to concatenating this buffer with others; the BOM should
|
||||
// only appear at the top of a file.
|
||||
line = line.substring(1); |
||||
} |
||||
|
||||
if (line !== null) { |
||||
stringBuffer.append(line); |
||||
} |
||||
|
||||
while ((line = input.readLine()) !== null) { |
||||
stringBuffer.append(lineSeparator); |
||||
stringBuffer.append(line); |
||||
} |
||||
//Make sure we return a JavaScript string and not a Java string.
|
||||
content = String(stringBuffer.toString()); //String
|
||||
} finally { |
||||
input.close(); |
||||
} |
||||
callback(content); |
||||
}; |
||||
} else if (masterConfig.env === 'xpconnect' || (!masterConfig.env && |
||||
typeof Components !== 'undefined' && Components.classes && |
||||
Components.interfaces)) { |
||||
//Avert your gaze!
|
||||
Cc = Components.classes; |
||||
Ci = Components.interfaces; |
||||
Components.utils['import']('resource://gre/modules/FileUtils.jsm'); |
||||
xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc); |
||||
|
||||
text.get = function (url, callback) { |
||||
var inStream, convertStream, fileObj, |
||||
readData = {}; |
||||
|
||||
if (xpcIsWindows) { |
||||
url = url.replace(/\//g, '\\'); |
||||
} |
||||
|
||||
fileObj = new FileUtils.File(url); |
||||
|
||||
//XPCOM, you so crazy
|
||||
try { |
||||
inStream = Cc['@mozilla.org/network/file-input-stream;1'] |
||||
.createInstance(Ci.nsIFileInputStream); |
||||
inStream.init(fileObj, 1, 0, false); |
||||
|
||||
convertStream = Cc['@mozilla.org/intl/converter-input-stream;1'] |
||||
.createInstance(Ci.nsIConverterInputStream); |
||||
convertStream.init(inStream, "utf-8", inStream.available(), |
||||
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); |
||||
|
||||
convertStream.readString(inStream.available(), readData); |
||||
convertStream.close(); |
||||
inStream.close(); |
||||
callback(readData.value); |
||||
} catch (e) { |
||||
throw new Error((fileObj && fileObj.path || '') + ': ' + e); |
||||
} |
||||
}; |
||||
} |
||||
return text; |
||||
}); |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/heroku/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/github/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/repo/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_github/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_org/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_other/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_auth_portions/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_local/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/flask_heroku/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
|
||||
<url> |
||||
<loc>https://pages.charlesreid1.com/github-heroku-attack-rabbits/custom_domains/</loc> |
||||
<lastmod>2018-06-17</lastmod> |
||||
<changefreq>daily</changefreq> |
||||
</url> |
||||
|
||||
|
||||
</urlset> |