Skip to content

Commit

Permalink
Merge pull request #2 from ECN/create-package-filestructure
Browse files Browse the repository at this point in the history
Create package filestructure
  • Loading branch information
benne238 authored Mar 12, 2021
2 parents 63aab7d + bb81c11 commit cdec7b6
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 753 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Ignore VS Code Config
.vscode/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -126,4 +129,4 @@ venv.bak/
dmypy.json

# Pyre type checker
.pyre/
.pyre/
File renamed without changes.
Empty file added __init__.py
Empty file.
62 changes: 57 additions & 5 deletions api/api.py → api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
jwt_required, get_jwt_identity, jwt_refresh_token_required,
set_refresh_cookies, unset_refresh_cookies
)
from werkzeug.security import check_password_hash
import os, dotenv
from easyad import EasyAD
from ldap.filter import escape_filter_chars
# pylint says this is an error but it works so ¯\_(ツ)_/¯
from ldap import INVALID_CREDENTIALS as LDAP_INVALID_CREDENTIALS
import ECNQueue

# Load envrionment variables for ./.env
Expand Down Expand Up @@ -47,6 +50,57 @@



def user_is_valid(username: str, password: str) -> bool:
"""Checks if user is valid and in webqueue2 login group.
Args:
username (str): Career account username.
password (str): Career account passphrase.
Returns:
bool: True if user is valid, otherwise False.
"""

# Check for empty arguments
if (username == "" or password == ""):
return False

# Initialize EasyAD
config = {
"AD_SERVER": "boilerad.purdue.edu",
"AD_DOMAIN": "boilerad.purdue.edu"
}
ad = EasyAD(config)

# Prepare search critiera for Active Directory
credentials = {
"username": escape_filter_chars(username),
"password": password
}
attributes = [ 'cn', "memberOf" ]
filter_string = f'(&(objectClass=user)(|(sAMAccountName={username})))'

# Do user search
try:
user = ad.search(credentials=credentials, attributes=attributes, filter_string=filter_string)[0]
except LDAP_INVALID_CREDENTIALS:
return False

# Isolate group names
# Example:
# 'CN=00000227-ECNStuds,OU=BoilerADGroups,DC=BoilerAD,DC=Purdue,DC=edu' becomes
# `00000227-ECNStuds`
user_groups = [ group.split(',')[0].split('=')[1] for group in user["memberOf"] ]

# Check group membership
webqueue_login_group = "00000227-ECN-webqueue"
if webqueue_login_group not in user_groups:
return False

return True



class Login(Resource):
def post(self) -> tuple:
"""Validates username/password and returns both access and refresh tokens.
Expand Down Expand Up @@ -76,10 +130,8 @@ def post(self) -> tuple:
if field not in data.keys():
return ({ "message": f"{field} missing from request body"}, 422)

if data["username"] != os.environ.get("SHARED_USERNAME"):
return ({ "message": "Username invalid"}, 401)
if not check_password_hash(os.environ.get("SHARED_PASSWORD_HASH"), data["password"]):
return ({ "message": "Password invalid"}, 401)
if not user_is_valid(data["username"], data["password"]):
return ({ "message": "Username or password is invalid"}, 401)

access_token = create_access_token(data["username"])
refresh_token = create_refresh_token(data["username"])
Expand Down
Loading

0 comments on commit cdec7b6

Please sign in to comment.