Repository: CTFd/CTFd

Issue:
Error on import: unsupported operand type(s) for +=: 'NoneType' and 'int'
**Environment**:

  - CTFd Version/Commit: 1.1.4
  - Operating System: Linux / Docker
  - Web Browser and Version: Latest Chrome

**What happened?**

Restoring from backup on the Web silently fails. Restoring from the command-line fails with:

```
/opt/CTFd # python import.py backup.zip 
 * Loaded module, <module 'CTFd.plugins.challenges' from '/opt/CTFd/CTFd/plugins/challenges/__init__.pyc'>
 * Loaded module, <module 'CTFd.plugins.keys' from '/opt/CTFd/CTFd/plugins/keys/__init__.pyc'>
Traceback (most recent call last):
  File "import.py", line 16, in <module>
    import_ctf(sys.argv[1], segments=segments)
  File "/opt/CTFd/CTFd/utils.py", line 951, in import_ctf
    entry[k] += chals_base
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'
/
```

**What did you expect to happen?**

My settings and data would be restored.

**How to reproduce your issue**

I'm trying to load data from an October deployment into a current version and I'm facing those problems.

**Any associated stack traces or error logs**

See above.


Discussion:
This is probably related to https://github.com/CTFd/CTFd/issues/567

This happens because CTFd is trying to normalize ID numbers so that you can stack imports together with existing data. Doesn't really work very well. 

Something is likely tripping up b/c the export has something that should reference a challenge but doesn't. I think the simplest thing to do is unzip your export and see if you can identify that and fix it up. 
I think these are caused by files entries that have no corresponding challenge:

```json
    {
      "id": 4, 
      "chal": 5, 
      "location": "57a3b12ba0d4e6c3942f2722a4b4a277/forensics100.pcap"
    }, 
    {
      "id": 5, 
      "chal": 6, 
      "location": "b5859193017ffc8920e43e682d8b2065/forensics200.pcap"
    }, 
    {
      "id": 6, 
      "chal": null, 
      "location": "90af9383ea3400b8474dab56ce3084df/challenge.jpg"
    }, 
    {
      "id": 7, 
      "chal": null, 
      "location": "fc4375391948580dabd356adefccb821/nsec.png"
    }
  ],
```

```python
                    for k, v in entry.items():
                        if k == 'chal' or k == 'chalid':
                            entry[k] += chals_base
```

This becomes: `null += 0`. Not sure what the proper fix would be... Should a chalid 0 be reserved for files not associated with a challenge?
Good point I think the simple fix is to just do 

```
if entry[k]:
    entry[k] += chals_base
```
Give that a shot and see if it fixes your issue and I can implement it here before it gets all rewritten. 
Yeah I dug through some old plugins I have and it seems like I did implement 

```python

                            if k == 'chal' or k == 'chalid':
                                if entry[k]:
                                    entry[k] += chals_base
                            if k == 'team' or k == 'teamid':
                                if entry[k]:
                                    entry[k] += teams_base
```

So it looks like that's a correct fix

Resolving patch:
diff --git a/CTFd/utils.py b/CTFd/utils.py
--- a/CTFd/utils.py
+++ b/CTFd/utils.py
@@ -948,9 +948,11 @@ def import_ctf(backup, segments=None, erase=False):
                                     continue
                     for k, v in entry.items():
                         if k == 'chal' or k == 'chalid':
-                            entry[k] += chals_base
+                            if entry[k]:
+                                entry[k] += chals_base
                         if k == 'team' or k == 'teamid':
-                            entry[k] += teams_base
+                            if entry[k]:
+                                entry[k] += teams_base
 
                     if item == 'teams':
                         table.insert_ignore(entry, ['email'])


Test patch: